为什么除了最后一个

时间:2019-07-16 23:23:07

标签: c++ gdb x86-64 disassembly callstack

我正在通过反汇编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

可以理解:崩溃是由于取消了对ptr的引用而导致的。现在,让我们一举成名,并在那里查看反汇编输出:

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

什么?上面的框架正在运行测试?它不应该调用在第0帧中反汇编的函数吗?我有什么误会?

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

1 个答案:

答案 0 :(得分:4)

  

我误会什么?

x86(和x86_64)上,CALL指令将 next 指令的地址压入堆栈,并跳转到被调用的函数。 / p>

当您转到up时,当前指令是您刚从退回的那一帧返回后将执行的指令。

如果要查看实际的x/i $pc-5,请执行CALL(注意:-5适用于大多数(但不是全部)CALL。请参见下面的Peter Cordes评论)