CatCoding

Cflow 分析

2011-03-09

cflow

cflow是个比较古老的程序 (好像比我老一岁),主要是用来打印 C 程序的函数调用关系,通过函数调用关系能大概看一下程序的流程。最近看了一下这个程序的代码,主要分为两个小程序组成。首先是 prcc.c 这个程序,作用是读源文件,提取出函数名称,然后生成一个函数列表。第一列是调用函数,第二列是被调用的函数名称 (如果是函数声明则这两列相同)。第二个程序 prcg.c 是读取函数关系,里面建起一个有向无环图。根据这个图加上缩进打印出函数调用轮廓,这里有一个例子。最后是一个脚本 cflow.sh,其核心代码就是。

prcc demo.c | prcg

这是典型的通过管道把小程序组起来的例子。

life is short , use Python


闲着的时候在这个程序上做了些小工作。既然有了第一个程序,那也可以用 python 来快速写个程序继续做些工作。首先想到的是写个程序把函数名打印出来,在有调用关系的函数之间用直线连起来。python 就是容易实现。这里有一个问题,就是怎么排列函数名的位置,使得连线不怎么相交,因为相交起来就不容易看到函数之间的关系了。不好解决,还是用了以前《集体智慧编程》里面的优化函数,也就是优化问题。通用思路就是试着移动各个函数的位置,朝着相交点最少的部分移动 (这里给一个解,相交点的个数为评估函数)。效果不是很好,当函数比较多的时候哪种算法都比较慢,而且交点看起来不可避免。这是一个结果。运行方法是:

prcc demo.c | python drawfuncs.py

或者

find  *.c | xargs prcc| python drawfuncs.py

来处理多个程序。

screenscreen

然后又想着可以做一个标签一样的东西,把调用深度比较潜的放大,调用深度深的缩小。不连线,位置随机画。这样一眼能看出来这个程序的主要函数是哪些。结果成这样了。

screenscreen

位置随便画还是不好,可以分层。然后再相邻层之间的函数有调用关系的再用直线连起来,就变成这样了。清晰一点。既然有函数关系,其实是可以做到更好的,就像上面那个 prcg.c 程序,不过代码要复杂些了。

screenscreen

C 要的是运行速度,Python 实现速度快!

公号同步更新,欢迎关注👻