深入分析GCC
上QQ阅读APP看书,第一时间看更新

2.5 GCC调试选项

GCC本身对包含了众多的调试选项,既可以为用户程序生成调试信息,也可以将GCC运行过程中的关键信息保存在文件或输出在终端上,常用的调试选项如表2-2所示。如果需要了解GCC在处理的各个阶段里中间表示的具体内容,或者需要了解GCC中某个处理过程对于中间表示的处理细节时,就可以使用表2-2中给出的各种GCC调试选项,输出GCC运行过程中所生成的中间表示的调试信息和处理过程细节,并结合GCC的代码,从而了解GCC的具体工作细节。

表2-2 GCC主要的调试选项

例2-1 GCC调试选项的使用

假设有如下的源代码:

        [GCC@localhost test]$ cat test.c
        int main(){
          int i=0, sum=0;
          sum = sum + i;
          return sum;
        }

为了了解GCC对该文件编译过程中的主要处理过程,可以使用如下命令输出GCC处理过程的主要调试信息和工作流程。

        [GCC@localhost test]$ ~/paag-gcc/host-i686-pc-linux-gnu/gcc/cc1 -fdump-tree-all -fdump-
    rtl-all test.c
        [GCC@localhost test]$ ls test.c*
        test.c                      test.c.123t.optimized          test.c.168r.asmcons
        test.c.001t.tu              test.c.125t.blocks             test.c.171r.subregs_of_mode_init
        test.c.003t.original        test.c.126t.final_cleanup      test.c.172r.ira
        test.c.004t.gimple          test.c.128r.expand             test.c.173r.subregs_of_mode_finish
        test.c.006t.vcg             test.c.129r.sibling            test.c.176r.split2
        test.c.007t.useless         test.c.131r.initvals           test.c.178r.pro_and_epilogue
        test.c.010t.lower           test.c.132r.unshare            test.c.192r.stack
        test.c.011t.ehopt           test.c.133r.vregs              test.c.193r.alignments
        test.c.012t.eh              test.c.134r.into_cfglayout     test.c.196r.mach
        test.c.013t.cfg             test.c.135r.jump               test.c.197r.barriers
        test.c.014t.cplxlower0      test.c.154r.reginfo            test.c.200r.eh_ranges
        test.c.015t.veclower        test.c.157r.outof_cfglayout    test.c.201r.shorten
        test.c.021t.cleanup_cfg     test.c.163r.split1             test.c.202r.dfinish
        test.c.023t.ssa             test.c.165r.dfinit             test.c.203t.statistics
        test.c.038t.release_ssa     test.c.166r.mode_sw

可以看出,此时输出的各种调试文件名称格式为:test.c.nnn[r/t].name,其中nnn为一个编号,t表示该处理过程是基于tree的GIMPLE处理过程,r表示该处理过程是基于RTL的处理过程。如果读者关注函数控制流图(CFG, Control F low Graph)的信息,那么可以打开test.c.013t.cfg文件,查看其中的具体内容。内容如下:

        [GCC@localhost test]$ cat test.c.013t.cfg
        ;; Function main (main)
        Merging blocks 2 and 3
        main ()
        {
          int sum;
          int i;
          int D.1234;

        <bb 2>:
          i = 0;
          sum = 0;
          sum = sum + i;
          D.1234 = sum;
          return D.1234;
        }

其中就包含了例子中给出函数的控制流图,如果想了解更详细的CFG信息,也可以使用如下的编译形式:

        [GCC@localhost test]$ ~/paag-gcc/host-i686-pc-linux-gnu/gcc/cc1 -fdump-tree-cfg-
    all test.c
        [GCC@localhost test]$ cat test.c.013t.cfg
        ;; Function main (main)
        Scope blocks:
        { Scope block #0
          intD.0 iD.1232; (unused)
          intD.0 sumD.1233; (unused)
        }
        Pass statistics:
        ----------------
        Merging blocks 2 and 3
        main ()
        {
          intD.0 sumD.1233;
          intD.0 iD.1232;
          intD.0 D.1234;
          # BLOCK 2
          # PRED: ENTRY (fallthru)
          iD.1232 = 0;
          sumD.1233 = 0;
          sumD.1233 = sumD.1233 + iD.1232;
          D.1234 = sumD.1233;
          return D.1234;
          # SUCC: EXIT
        }

可以看出,GCC编译时会生成更加详细的CFG信息。

读者也可以根据自己的需要,合理地使用表2-2中的调试选项,输出GCC编译过程中感兴趣的调试信息,从而分析GCC的工作细节。