绘制函数调用关系图(call graph),对开发人员理解源码有非常大的帮助,特别是在以下情况:
- 大型项目,庞杂的代码量;
- 项目文档缺失,特别是设计文档、流程图的缺失;
- 第三方代码库,如开源项目;
- 检查实际函数调用关系跟规划的设计是否一致,以免出错。
绘制函数调用关系图的途径主要有两种,一种是人工手动绘制(很多人应该都有一边看代码(或借助调试工具单步跟踪),一边在纸上画函数调用关系图的经历),另一种是使用工具自动绘制。
自动分析函数调用关系的工具,主要分为「静态分析」和「动态分析」两种。所谓静态分析是指在不运行待分析的程序的前提下进行分析,那么动态分析自然就是记录程序实际运行时的函数调用情况了。更详细的分类,可以参考以下文章:
https://blog.youkuaiyun.com/solstice/article/details/488865
动态调用图是精确的,但仅描述程序的一次运行。 静态调用图是旨在表示程序的每个可能运行的调用图。 确切的静态调用图是一个不可判定的问题,所以静态调用图算法通常是过度的。 也就是说,发生的每个调用关系都在图中表示,并且可能还有一些调用关系在程序的实际运行中永远不会发生。
以下网址列举了这方面的工具:
https://en.wikipedia.org/wiki/Call_graph
大部分的工具,都是将函数调用关系的分析结果以文本的形式输出,你还需要利用第三方工具将文本文件转为图片文件,大部分都是使用可视化工具 graphviz 转化为图片(这个转化过程涉及到 dot 语言)。
针对C/C++语言,我体验了几款开源的、静态分析的工具:cflow、codeviz 和 doxygen,看看效果如何。截止书稿,前两者用的的人已经越来越少了,用doxygen的比较多,从谷歌趋势图就能看出这点:

以下是我体验过程,把他们整理出来供大家参考。
绘制函数调用图(call graph)(2):cflow + graphviz
绘制函数调用图(call graph)(3):codeviz + graphviz
绘制函数调用图(call graph)(4):doxygen + graphviz