《深入分析GCC 》——2.5 GCC调试选项

本节书摘来自华章出版社《深入分析GCC 》一书中的第2章,第2.5节,作者 王亚刚 ,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.5 GCC调试选项

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


《深入分析GCC 》——2.5 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的工作细节。

上一篇:MySql的数据查询


下一篇:《深入分析GCC 》导读