了解进入标签时"堆栈"在 gdb 中显示的内容



我有以下程序集:

_start:    
mov $strings,   %rbx
mov $1,         %r12d
print_loop:
mov %rbx,       %rdi

它很简单,但以下是它在gdb中为这三行/指令中的每一行显示的内容:

  1. mov $strings, %rbx

    0x00000000004000c4  ? mov    $0x6000ea,%rbx # memory address of 'strings'
    ─── Stack ──────────────────────────────────────────────────────────────────────────────────────────────────────
    [0] from 0x00000000004000c4 in _start
    
  2. mov $1, %r12d

    0x00000000004000cb  ? mov    $0x1,%r12d
    ─── Stack ───────────────────────────────────────────────────────────────────────────────────────────────────────
    [0] from 0x00000000004000cb in _start
    
  3. 但在第三条指令上——标签后的第一条指令上,情况看起来很不稳定:

    0x00000000004000d1  ? mov    %rbx,%rdi
    ─── Stack ───────────────────────────────────────────────────────────────────────────────────────────────────────
    [0] from 0x00000000004000d1 in print_loop
    [1] from 0x0000000000000001
    [2] from 0x00007fffffffe5aa
    [3] from 0x0000000000000000
    

这到底意味着什么,为什么它会显示这样的东西?堆栈似乎仍然应该显示一行:

[0] from 0x00000000004000d1 in print_loop
- or - 
[0] from 0x00000000004000d1 in _start

这到底意味着什么,

这意味着GDB认为您正在print_loop函数内部执行,并且它认为此函数是从地址0x1的某些代码调用的,而地址0x7fffffffe5aa等则是从

为什么它会显示这样的东西?

它很混乱。

堆栈似乎仍然应该显示一行:

正确。


现在,你的下一个问题可能是";为什么GDB会感到困惑&";。

答案有些复杂。

在不使用专用帧指针寄存器的平台上,如x86_64,GDB没有通用的方法来展开堆栈,需要编译器的帮助;展开台";,GDB将其解释为执行堆叠展开。

由于您是在程序集中编写的,并且没有使用.cfi_...指令,因此您的代码没有任何展开描述符。

在没有展开描述符的情况下,GDB只能猜测,而这里的猜测是错误的。

要解决此问题,可以提供展开描述符,类似于以下内容(未经测试(:

_start:
.cfi_startproc
.cfi_undefined(rip)     # no unwinding past this function    
mov $strings,   %rbx
mov $1,         %r12d
print_loop:
mov %rbx,       %rdi
...
.cfi_endproc

这应该会解开GDB。可以在此处找到各种.cfi指令的文档。

最新更新