这是 的记录行为gdb
,并且(应该是)可配置的。
gcc 4.7.2
当我用( )编译您的代码时-O3
,我得到以下程序集:
_main:
LFB1:
movl _i.2134(%rip), %eax
cmpl $10, %eax
jle L6
xorl %eax, %eax
ret
L6:
addl $1, %eax
pushq %rdx
LCFI0:
movl %eax, _i.2134(%rip)
xorl %eax, %eax
call _main ; <=== recursive call
popq %rcx
LCFI1:
movl $101, %esi
xorl %eax, %eax
leaq LC0(%rip), %rdi
jmp _printf
LFE1:
这反驳了递归调用被优化掉的假设。
现在,如果我将二进制文件加载到 中gdb
并在 上设置断点main()
,它会被反复命中。当我检查寄存器时,%rsp
每次调用都会递减,因此显然有与每个main()
.
尽管如此,bt
只显示一个帧:
(gdb) bt
#0 0x0000000100000f50 in main ()
(在这种情况下,我知道有三main()
帧,而不仅仅是一帧。)
因此,我得出结论,这与gdb
它本身有关。
经过进一步调查,事实证明这种行为已记录在案:
大多数程序都有一个标准的用户入口点——系统库和启动代码转换为用户代码的地方。对于 C,这是main
. 当gdb
在回溯中找到入口函数时,它将终止回溯,以避免追踪到高度系统特定(通常是无趣)的代码。
当我在中设置以下内容时gdb
:
set backtrace past-main on
set backtrace past-entry on
它开始显示两main()
帧。出于某种原因,它仍然没有更深入。