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

标签 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

有道理:崩溃是由于空指针取消引用而发生的。现在让我们看看那里的反汇编输出:

(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/

相关文章:

c++ - Valgrind 赋值错误

c++ - 在GDB中查看打印方法

performance - 充分利用卡比湖上的管道

c++ - 转换 - 在 C++ 中 float 的 ASCII 十六进制

C++ - 使用 atoi() 时出现未处理的异常

c++ - 关于调试核心文件C++/linux的一些基本问题?

c - 在没有原型(prototype)的文件中调用的函数在ARM和x86-64上产生不同的结果

c++ - 用于多态调用的 x86-64 汇编器

c++ - 虚函数的动态绑定(bind)

c++ - 错误 : anachronistic old-style base class initializer