欢迎来到天天文库
浏览记录
ID:12174614
大小:19.01 KB
页数:4页
时间:2018-07-16
《分析函数调用关系图(call graph)的几种方法》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、分析函数调用关系图(callgraph)的几种方法绘制函数调用关系图对理解大型程序大有帮助。我想大家都有过一边读源码(并在头脑中维护一个调用栈),一边在纸上画函数调用关系,然后整理成图的经历。如果运气好一点,借助调试器的单步跟踪功能和callstack窗口,能节约一些脑力。不过如果要分析的是脚本语言的代码,那多半只好老老实实用第一种方法了。如果在读代码之前,手边就有一份调用图,岂不妙哉?下面举出我知道的几种免费的分析C/C++函数调用关系的工具。函数调用关系图(callgraph)是图(graph),而且是有向图,多
2、半还是无环图(无圈图)——如果代码中没有直接或间接的递归的话。Graphviz是专门绘制有向图和无向图的工具,所以很多callgraph分析工具都以它为后端(backend)。那么前端呢?就看各家各显神通了。调用图的分析分析大致可分为“静态”和“动态”两种,所谓静态分析是指在不运行待分析的程序的前提下进行分析,那么动态分析自然就是记录程序实际运行时的函数调用情况了。静态分析又有两种方法,一是分析源码,二是分析编译后的目标文件。分析源码获得的调用图的质量取决于分析工具对编程语言的理解程度,比如能不能找出正确的C++重载
3、函数。Doxygen是源码文档化工具,也能绘制调用图,它似乎是自己分析源码获得函数调用关系的。GNUcflow也是类似的工具,不过它似乎偏重分析流程图(flowchart)。对编程语言的理解程度最好的当然是编译器了,所以有人想出给编译器打补丁,让它在编译时顺便记录函数调用关系。CodeViz(其灵感来自MartinDevera(Devik)的工具)就属于此类,它(1.0.9版)给GCC3.4.1打了个补丁。另外一个工具egypt的思路更巧妙,不用大动干戈地给编译器打补丁,而是让编译器自己dump出调用关系,然后分析分
4、析,交给Graphviz去绘图。不过也有人另起炉灶,自己写个C语言编译器(ncc),专门分析调用图,勇气可嘉。不如要是对C++语言也这么干,成本不免太高了。分析C++的调用图,还是借助编译器比较实在。分析目标文件听起来挺高深,其实不然,反汇编的工作交给binutils的objdump去做,只要分析一下反汇编出来的文本文件就行了。下面是Cygwin下objdump-da.exe的部分结果:00401050<_main>: 401050: 55 push %ebp 40
5、1051: 89e5 mov %esp,%ebp 401053: 83ec18 sub $0x18,%esp ...... 40107a: c7442404002040 movl $0x402000,0x4(%esp) 401081: 00 401082: c7042402204000 movl $0x402002,(%esp) 401089: e8f2000000
6、 call 401180<_fopen>从中可以看出,main()调用了fopen()。CodeViz带有分析目标文件的功能。动态分析是在程序运行时记录函数的调用,然后整理成调用图。与静态分析相比,它能获得更多的信息,比如函数调用的先后顺序和次数;不过也有一定的缺点,比如程序中语句的某些分支可能没有执行到,这些分支中调用的函数自然就没有记录下来。动态分析也有两种方法,一是借助gprof的callgraph功能(参数-q),二是利用GCC的 -finstrument-functions 参数。gprof生成的输
7、出如下:index%time self children called name 0.00 0.00 4/4 foo[4][3] 0.0 0.00 0.00 4 bar[3]----------------------------------------------- 0.00 0.00 1/2 init[5] 0.0
8、0 0.00 1/2 main[45][4] 0.0 0.00 0.00 2 foo[4] 0.00 0.00 4/4 bar[3]-----------------------------------------
此文档下载收益归作者所有