在我们向程序猿进军的过程中阅读别人的代码总是难以避免的,我们常常都喜欢阅读自己的代码而不喜欢阅读别人的代码,归根结底都是由于人与人之间的思维不太可能完全一样,这种思维之间的差异造成了阅读别人代码的障碍。
在我阅读别人的代码过程中,最让我痛苦的事儿就是每一个语法我都认识,但是我就不知道他想干什么!但是,如果代码的作者把他的思路告诉了你,给你画了流程图什么的,你就会较为容易的阅读源代码了,这个就是文档的重要性。因为文档给了你大致的方向,你可以从宏观的角度去审视代码,而不是陷于代码细节之中,让自己一阵阵头大。
我今天写这篇博文的原因只有一个,我发现了一种可以分析代码之间相互调用的工具,而且这种工具还是DIY的,让我震惊了一小把
虽然是别人05年写的这篇文章《用Graphviz可视化函数调用》,但是不得不说,这个东西真的很有用,今天晚上实验了一下,效果很不错,下面是我自动生成的调用关系图:
[![](http://zt2peilong-wordpress.stor.sinaapp.com/uploads/2013/12/graph.jpg "graph")](http://zt2peilong-wordpress.stor.sinaapp.com/uploads/2013/12/graph.jpg)
代码如下:
#include
void level2()
{
printf("f1\n");
}
void level1()
{
printf("f2\n");
level2();
}
main()
{
level2();
level1();
}
M. Tim Jones是如何实现的呢?
- M. Tim Jones他主要是运用了gcc编辑器的-finstrument-functions[1]这个编辑选项,这个编辑选项可以在每个函数的调用的入口以及返回出记录下当前函数的地址以及调用该函数的地址,我们只要有了这个关系,我们就可以得到各个函数之间的调用关系了。
- 当然我们这个时候得到的还只是地址码,我们还需要借助addr2line[2]这个小工具把地址码转换成我们喜欢的函数名字,这样子我们才能方便的可视化。
- 有了这些数据之后,我们又要使用一个工具叫做Graphviz,它使用了一种叫做DOT的语言(很简单的一种描述性的语言),可以很方便的把各个模块之间的关系给标示出来,并生成图片。
这样,我们的可视化函数调用图就可以完成了。
后记
这种自动生成的函数调用关系图对于我们学习那些开源源码的时候很有帮助,比如像nginx,这里面很多都是函数指针,你直接阅读源码估计看晕的可能性比较大,有了这种动态的关系分析图了之后,我们就可以在宏观上对整个程序有个大体的了解,让我们的学习更加有效率。
相关资料:
[1] gcc –finstrument-functions特性的应用
[2]addr2line简介
[3]GrapHviz官网