0

我在main()里面打电话main(),递归10次。现在在使用gdb(bt/backtrace) 进行调试时,我没有看到main(). 为什么?

#include<stdio.h>

int main(){

     static int i;
     int num=100;

     if(i>10)
       return 0;
     else {
       i++;
       num++;
       main();
       printf("\n%d",num); 
     }
 }
4

3 回答 3

4

这是 的记录行为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()帧。出于某种原因,它仍然没有更深入。

于 2012-12-19T10:25:30.120 回答
2

您的问题与您为此使用的事实无关main

一个简单的递归程序,正如您最终愿意在评论中向我们展示的那样,可以很容易地被编译器优化,根本不进行递归。在您的情况下,它比通常更简单,因为您有一个预定义的递归深度10. 编译器可以轻松地将其展开为静态代码。

于 2012-12-19T10:09:06.957 回答
1
Here is the Answer for my own Question.
(gdb) set backtrace past-main on
(gdb) b main
Breakpoint 1 at 0x4004b0: file recursion.c, line 5.
(gdb) run
Starting program: /nobackup/arjprasa/C/gdb/a.out

Breakpoint 1, main () at recursion.c:5
5               int num=100;
(gdb) c
Continuing.

Breakpoint 1, main () at recursion.c:5
5               int num=100;
(gdb) bt
#0  main () at recursion.c:5
#1  0x00000000004004df in main () at recursion.c:12
#2  0x00000034d091c4cb in __libc_start_main () from /lib64/tls/libc.so.6
#3  0x000000000040041a in _start ()
(gdb) c
Continuing.

Breakpoint 1, main () at recursion.c:5
5               int num=100;
(gdb) bt
#0  main () at recursion.c:5
#1  0x00000000004004df in main () at recursion.c:12
#2  0x00000000004004df in main () at recursion.c:12
#3  0x00000034d091c4cb in __libc_start_main () from /lib64/tls/libc.so.6
#4  0x000000000040041a in _start ()
(gdb) c
Continuing.

Breakpoint 1, main () at recursion.c:5
5               int num=100;
(gdb) bt
#0  main () at recursion.c:5
#1  0x00000000004004df in main () at recursion.c:12
#2  0x00000000004004df in main () at recursion.c:12
#3  0x00000000004004df in main () at recursion.c:12
#4  0x00000034d091c4cb in __libc_start_main () from /lib64/tls/libc.so.6
#5  0x000000000040041a in _start ()
(gdb)
于 2012-12-19T12:08:34.810 回答