我正在通过 gdb 的反汇编输出来分析核心事后分析。我对此很陌生,所以我对我所看到的内容的理解仍在不断增长。对我来说,一个直接的困惑是,当我在帧之间切换并查看反汇编输出时,我没有看到 callq 命令作为正在运行的命令,正如我对所有非帧 0 帧所期望的那样。难道不是应该在第 0 帧之前的每个帧都调用一个函数吗?
(gdb) f 0
(gdb) disassemble
...
=> 0x0000000001b0af10 <+16>: mov (%rdi),%rdx
...
End of assembler dump.
(gdb) info registers rdi
rdi 0x0 0
有道理:崩溃是由于空指针取消引用而发生的。现在让我们看看那里的反汇编输出:
(gdb) up
(gdb) disassemble
...
=> 0x0000000001b1c01b <+315>: test %al,%al
...
什么?上面的框架正在运行测试?难道不应该调用第0帧中反汇编的函数吗?我有什么误解吗?
这是由 GCC 4.8 编译 C++ 代码生成的 x64 程序集。
最佳答案
What am I misunderstanding?
在 x86
(和 x86_64
)上,CALL
指令将下一条指令的地址压入堆栈,并跳转到被调用的函数。
当您向上
时,当前指令是在您刚刚从返回处向上迈进的帧之后将执行的指令。
如果您想查看实际的CALL
,请执行x/i $pc-5
(注意:-5
适用于大多数情况,但不是所有 CALL
。请参阅下面的 Peter Cordes 评论)。
关于c++ - 为什么除了最后一帧之外,反汇编的每一帧都没有调用命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57066631/