我正在调试以下程序(正确)。
[OP@localhost 04]$ cat factorial.s
.section .text
.globl _start
.globl _factorial
_start:
push $4
call factorial
add $8, %rsp
mov %rax, %rdi
mov $60, %rax
syscall
.type factorial, @function
factorial:
# Parameters
# n : int
# Number to take factorial of
push %rbp
mov %rsp, %rbp
mov 0x10(%rbp), %rax
if:
cmp $1, %rax
jne else
jmp end_if
else:
dec %rax
push %rax
call factorial
add $8, %rsp
imul 0x10(%rbp), %rax
end_if:
pop %rbp
ret
我已经在阶乘函数上设置了一个断点,然后继续两次。检查%rsp的值,我发现它是
(gdb) print/$rsp
$1 = 0x7fffffffd698
检查周围的区域,我发现
(gdb) x /10xg 0x7fffffffd690
0x7fffffffd690: 0x0000000000000000 0x00007fffffffd6b0
0x7fffffffd6a0: 0x0000000000401030 0x0000000000000002
0x7fffffffd6b0: 0x00007fffffffd6c8 0x0000000000401030
0x7fffffffd6c0: 0x0000000000000003 0x0000000000000000
0x7fffffffd6d0: 0x0000000000401007 0x0000000000000004
大致上,这就是人们所期望的。但是,where
的输出如下:
(gdb) where
#0 0x000000000040101b in factorial ()
#1 0x0000000000401030 in else ()
#2 0x0000000000000002 in ?? ()
#3 0x00007fffffffd6c8 in ?? ()
#4 0x0000000000401030 in else ()
#5 0x0000000000000003 in ?? ()
#6 0x0000000000000000 in ?? ()
我似乎无法理解。似乎是按顺序读取堆栈,但我不知道数字0x40101b的来源(该数字在堆栈中不存在),而且我不确定为什么它停在那里,因为它不会打印出初始函数调用factorial
的堆栈帧。
答案 0 :(得分:1)
但是,where的输出如下:
在x86_64
上,GDB希望程序具有适当的DWARF
展开信息(您的程序完全缺少该信息)。 ({Documentation关于如何使用.cfi
指令插入此类信息。)
在没有DWARF
信息的情况下,GDB会使用某些启发式方法进行猜测。 GDB在这里将else
视为函数,并尝试找到其调用方,结果很糟糕。实际上,where
在没有DWARF
展开信息的情况下不适用于程序,除非该程序仅使用C
功能标签并使用帧指针。