上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的工作细节。