一、基于 Doxygen或 lxr 的API形式的文档系统。

二、基于CodeViz, CodeViz是《Understanding The Linux Virtual Memory Manager》的作者 Mel Gorman 写的一款分析C/C++源代码中函数调用关系的open source工具(类似的open source软件有 egyptncc)。属于编译器级别的分析工具。

三、基于cflow、dot(即graphviz)等系列软件。属于源码直接解析类的分析工具。

四、基于egypt, 比较推荐这个,因为它支持 arm。它不用大动干戈地给编译器打补丁,而是让编译器自己dump出调用关系,然后分析分析,交给Graphviz去绘图。属于编译器级别的分析工具。

一、略。

二、基于CodeViz,主要是Graphviz + CodeViz,一个分析,一个画图。

三、基于cflow、dot(graphviz)。用于源码分析比较合适,无法从编译器视角去分析。参看:

www.tinylab.org/callgraph-draw-the-calltree-of-c-functions/?utm_source=tuicool&utm_medium=referral

值得说明的是,cflow无法直接对目录进行recursive分析,它只支持文件分析,即必须手动把要分析的文件指定给它,如: cflow -b  -m fib ./h/fib.c ./cc/fi.c ./ccc/fi.c

而且,如果 ./h/fib.c  ./cc/fi.c  ./ccc/fi.c 中有重名的函数,则这些同名函数的调用关系会合并,即若./cc/fi.c 中有个函数a只调用了函数b,而./ccc/fi.c中也有个函数a只调用了函数c,则最后打印出来的结果是函数a同时调用了b和c,即合并了。
对于cflow系列工具的使用,因为它输出的不是图形化的调用关系,因此这里推荐使用www.tinylab.org的组合工具:calltree。 它整合了cflow及graphviz并附带了一个将C 函数调用树转换为 dot 格式的脚本:tree2dotx:以 Ubuntu 为例,分别安装它们:

$ sudo apt-get install cflow graphviz
$ wget -c https://github.com/tinyclub/linux-0.11-lab/raw/master/tools/tree2dotx
$ wget -c https://github.com/tinyclub/linux-0.11-lab/raw/master/tools/callgraph
$ sudo cp tree2dotx callgraph /usr/local/bin
$ sudo chmod +x /usr/local/bin/{tree2dotx,callgraph}
$ sudo apt-get install gawk

我已经把tree2dotx 及 callgraph 放入到了自己的云盘

使用方法:

$ callgraph -f start_kernel -d init/main.c                 #只在文件init/main.c里打印函数start_kernel里的所有调用关系图
$ callgraph -f start_kernel -d init/main.c -F printk       #可用 -F 过滤掉不需要打印的函数
$ callgraph -f start_kernel -d init/main.c -F "printk boot_cpu_init rest_init"      #可用 -F 过滤掉不需要打印的多个函数
$ callgraph -f start_kernel -d init/main.c -F "printk boot_cpu_init rest_init" -D 2    # 用 -D 指定函数的搜索深度(同一个文件的)

由于callgraph这个脚本也无法对目录进行递归统计(cflow也无法),且callgraph用*(全部匹配)这种方法不起作用,但cflow用*方法可以匹配所有文件但不能匹配目录:

$ callgraph -f start_kernel -d init/*$ cflow -b  -m main example/* | /usr/local/bin/tree2dotx  2>/dev/null | dot -Tsvg -o ./main.svg    # 档example目录里没有任何目录(即全是文件)时才能执行成功,                                                                                                   # 若有任何目录,则执行失败$ cflow -b example/* | /usr/local/bin/tree2dotx  2>/dev/null | dot -Tsvg -o ./main.svg             # 不带 -m 选项,将列出所有函数的调用关系$ cflow -b example/* | /usr/local/bin/tree2dotx -f "printk boot_cpu_init rest_init" 2>/dev/null | dot -Tsvg -o ./main.svg     # 可以过滤掉 printk boot_cpu_init rest_init 函数的显示

因此有两种方法可以做到统计目录里的所有文件:一是修改callgraph这个脚本;二是手动列出example目录下的所有文件(包含子目录)输给cflow。

趣玩 tree2dotx

打印目录结构:

$ tree -L  | tree2dotx | dot -Tsvg -o tree.svg

四、基于egypt

注意,可以在CFLAGS中加入的-O0参数,禁止编译器优化。如果不禁止优化,有些函数可能会因为优化的关系而显示不出来。

编译时加入:

CFLAGS = $(CFLAGS) -fdump-rtl-expand

编译结束后,假设所有的 expand文件都位于 expand_dir 目录,则可以这样生成dot文件:

egypt expand_dir/* > example.dot若只想用一部分文件来生成调用图,则可以指定文件:
egypt expand_dir/f1.c.144r.expand  expand_dir/f2.c.184r.expand > example.dot
然后生成svg图片:dot example.dot -Tsvg -o example.svg

用 -Tpng 替换 -Tsvg 可以生成png图片,不过建议生成svg图片,因为它缩放不变形不模糊。

注意:如果函数太多,dot转换后的图片太大会打开失败,遇到这种情况可以使用dot的plain或者plain-ext格式来保存为纯文本(文本里的node指的是节点,edge指的是边,即指向),然后在纯文本里找到那些不需要的函数,重新用egypt的--omit去掉一些不需要的函数,直到dot转换后的图片能打开为止。或者直接看plain文本也可以。  纯文本里面的 solid ellipse black lightgrey 这些颜色、形状表示的是node或者edge的特征。

egypt 的命令格式:

egypt [--omit function,function,...] [--include-external] <rtl-file>... | dotty -
egypt [--omit function,function,...] [--include-external] <rtl-file>... | dot <dot-options>

omit

Omit the given functions from the call graph. Multiple function names may be given separated by commas.

include-external

Include calls to external functions in the call graph. A function is considered external if it is not defined in any of the input files. For example, functions in the standard C library are external. Only direct function calls will be displayed; there is no way to display the action of taking the address of an external function.

还有一个基于 egypt 的比较好用的分析工具: https://github.com/cbdevnet/rtl2dot/

c语言分析函数调用关系图(call graph)的几种方法的更多相关文章

  1. 分析函数调用关系图(call graph)的几种方法

    绘制函数调用关系图对理解大型程序大有帮助.我想大家都有过一边读源码(并在头脑中维护一个调用栈),一边在纸上画函数调用关系,然后整理成图的经历.如果运气好一点,借助调试器的单步跟踪功能和call sta ...

  2. 用CodeViz绘制函数调用关系图(call graph)

    CodeViz是<Understanding The Linux Virtual Memory Manager>(at Amazon,下载地址在页尾)的作者 Mel Gorman 写的一款 ...

  3. 用callgraph生成的函数调用关系图

    Wu Zhangjin 创作于 2015/04/05 评论打赏 By Falcon of TinyLab.org 2015/04/03 1 故事缘由 源码分析是程序员离不开的话题.无论是研究开源项目, ...

  4. 用callgraph生成的两张函数调用关系图

    参考这里,感觉很Cool吧. Linux-0.11函数调用关系图: QEMU函数调用关系图:

  5. python函数调用关系图(python call graph)

    由于要重构项目的部分代码,要整理好主要的函数调用关系,不想自己看代码慢慢画出结构,想找出一种通用的,节省人力的方法得出函数间的调用关系图,于是发现以下几个工具.(内网没装好graphviz,还没真正用 ...

  6. [转] 使用CodeViz生成C/C++函数调用关系图

    运行环境:虚拟机下的Ubuntu 11.04 结合Graphviz工具,使用CodeViz可以生成直观和漂亮的C/C++程序函数之间的调用关系图. 1.安装graphviz 在安装CodeViz之前, ...

  7. 使用Idea当中的快捷键快速查看继承关系或其图表的两种方法

    一.Idea当中有两种方法可以查看继承关系 在Idea当中选中一个类,然后按Ctrl+H,可以快速查看当前所选类的继承关系,如下图: ​ 同样选中一个类,按CTRL+ALT+U,即可生成当前类的继承关 ...

  8. C语言不使用加号实现加法运算的几种方法

    今天看到<编码:隐匿在计算机软硬件背后的语言>的第十二章:二进制加法器.讲述了全加器,半加器的原理以及如何实现加法.实现加法时所使用的全加器,半加器中包含的所有逻辑门在C语言中都有相应的运 ...

  9. 华为OJ机试题目:两个大整数相乘(纯C语言实现两个大整数相乘,两种方法实现大数相乘)

    题目描述: 输出两个不超过100位的大整数的乘积. 输入: 输入两个大整数,如1234567 123 输出: 输出乘积,如:151851741 样例输入: 1234567 123 样例输出: 1518 ...

随机推荐

  1. C#图片压缩的实现方法

    一般在web应用中,对客户端提交上来的图片肯定需要进行压缩的.尤其是比较大的图片,如果不经过压缩会导致页面变的很大,打开速度比较慢,当然了如果是需要高质量的图片也得需要生产缩略图. 一般在web应用中 ...

  2. HeadFirst Jsp 06 (会话管理)

    现在我们希望能够跨多个请求保留客户特定的状态. 现在, 模型中的业务只是检查请求中的参数, 并返回一个响应(建议), 应用中没有谁记得在当前请求之前与这个客户之间发生过什么. 与一个客户的整个会话期间 ...

  3. cocos2d-x 开启深度测试验 实现 遮挡

    CCDirector::sharedDirector()->setDepthTest(true); spr->setVertexZ(xxx);

  4. HTML5学习总结——HTML5新增属性与表单元素

    一HTML5新增属性 1.1contcxtmcnu contextmenu的作用是指定右键菜单. <!DOCTYPE html> <html> <head> < ...

  5. 用AngularJS开发的过程中如何查看Scope内容

    scope的继承就好比JS的原型链继承,深入理解Scope:http://www.lovelucy.info/understanding-scopes-in-angularjs.html 通过查看官网 ...

  6. Android 框架简介--Java环境(转)

    ==========================上=========================== 这里简单的介绍了Android的java环境基础,在后面一节中会结合具体的实例来理解这一节 ...

  7. Maven 安装Jar包到本地仓库

    开始cmd: 例1: mvn install:install-file -DgroupId=Issues -DartifactId=beautyeye -Dversion=3.5 -Dpackagin ...

  8. JProfiler 使用说明

    一个全功能的 Java 剖析工具( profiler ),专用于分析 J2SE 和 J2EE 应用程序.它把 CPU .执行绪和内存的剖析组合在一个强大的 应用中. JProfiler 可提供许多 I ...

  9. pg psql命令

    linux下使用psql命令操作数据库 下面主要用到了insert into  ,pg_dump  , pg_restore 命令 按步骤走 su postgres                   ...

  10. 【原创】搭建Nginx(负载均衡)+Redis(Session共享)+Tomcat集群

    为什么移除首页?哪里不符合要求?倒是回我邮件啊! 一.环境搭建 Linux下Vagrant搭建Tomcat7.Java7 二.Nginx的安装配置与测试 *虚拟机下转至root sudo -i 1)下 ...