为什么除了最后一帧外,反汇编的每一帧都没有调用命令

Why isn't a call command at each frame of disassemble except the last

我正在通过 gdb 的反汇编输出分析核心 post-mortem。我对此很陌生,所以我对我正在看的东西的理解仍在增长。我的一个直接困惑是,当我在帧之间移动并查看反汇编输出时,我没有看到 callq 命令是 运行 的命令,正如我对所有非帧 0 帧所期望的那样。不应该导致帧 0 的每个帧都调用一个函数吗?

(gdb) f 0
(gdb) disassemble
...
=> 0x0000000001b0af10 <+16>:    mov    (%rdi),%rdx
...
End of assembler dump.
(gdb) info registers rdi
rdi            0x0      0

有道理:崩溃是由于 null ptr 取消引用而发生的。现在让我们走红,看看那里的反汇编输出:

(gdb) up
(gdb) disassemble
...
=> 0x0000000001b1c01b <+315>:   test   %al,%al
...

什么?上图是运行ning测试?它不应该调用在第 0 帧中反汇编的函数吗?我误会了什么?

这是由 GCC 4.8 编译 C++ 代码生成的 x64 程序集。

What am I misunderstanding?

x86(和x86_64)上,CALL指令将下一条指令的地址压入堆栈,并跳转到调用的函数。

当你走到up时,当前指令就是你刚从returns开始的那一帧之后执行的指令。

如果您想查看实际的 CALL,请执行 x/i $pc-5(注意:-5 适用于大多数,但并非所有 CALL。参见 Peter Cordes 评论下面)。