平时我在阅读一些开源C/C++项目的源代码时,经常不知道整个工程里面的函数调用关系,如果是一个类似vs2010的工程,还好一些,毕竟有一个好用的IDE会方便很多。但如果是一个Linux项目,那么就比较郁闷了,这个时候,我经常用gdb来观察函数调用堆栈。经过良久的痛苦挣扎,我觉得应该自己写一个整理C/C++工程代码函数之间调用关系的小工具,以便帮助我快速了解整个工程的函数路由图。

   这个工程的GitHub地址为 https://github.com/jfu222/FuncRoute 。这个FuncRoute.exe是一个C++命令行程序,输入的参数格式说明如下:

Usage:
  .\FuncRoute.exe <in|dirs_include> <in|dirs_exclude> <out|out_pdf.tex> <in|max_num_of_rows_for_single_pdf_page>
For Example:
  .\FuncRoute.exe ./data1/src;./data2 ./data1/src/include;./data2/include ./out_pdf.tex 500

Notice:
     1) You can use command 'pdflatex ./out_pdf.tex' to create a pdf file which named './out_pdf.pdf'.
     2) dirs_include should be contain c/cpp files.
     3) dirs_exclude can be empty if you don't want it present. Such as "".
     4) max_num_of_rows_for_single_pdf_page must be in (0, 500]

目前最新的版本号为2.0.1.3。该工具大致工作流程如下:

1). 从用户输入的C/C++源代码路径下面,查找所有后缀为 .h,.hpp,.c,.cpp,.cc 的文本文件

2). 对查找到的文本文件,循环遍历每个文件,将每个文件中的C/C++函数名提取出来,保存到一个数组里面,并对每个函数名从1开始递增编号,即每个函数都有一个全局唯一编号

3). 对每个具有函数体定义的函数,提取出函数体里面调用的其他函数

4). 函数声明的函数名,和对应的函数体中被调用的各个函数,就构成了父节点和孩子节点,我称之为构成了一棵多叉树(相对于二叉树而言),一个函数声明对应一棵多叉树,只不过这棵树目前只有二层

5). 将上面构建的所有二叉树的孩子节点的孩子节点以类似链表的方式连接起来,构成一棵二层以上的多叉树,这棵多叉树即为我们需要的一个完整的函数调用关系路径树

6). 遍历上面的函数调用关系路径树,生产一个tex文本文件,该文件可以利用pdflatex命令生成一个pdf文件,这个pdf文件相当于一个可视化画图工具,就省去了单独开发可视化工具的工作量。

---------------------------------------------

下面是利用FuncRoute.exe生成的pdf截图:

分析FuncRoute工程自己

分析ffmpeg工程代码

分析JM工程代码

 

分析nginx工程

 

--------------------------------

该工具目前版本(FuncRoute.2.0.1.3.exe)的不足:

1. 只提取了C/C++工程代码中的函数名,未对C++类/结构体的变量进行充分分析

2. 对C++11等支持不够充分

3. 未对C/C++宏定义进行展开

4. 未进一步分析#include等C/C++预处理命令

5. 对于大型的C/C++工程分析时间比较久

6. 强依赖于pdflatex工具,利用pdflatex生成pdf有很多受到限制的地方

----------------------

计划2.1版本会补上上面的不足之处。(前提是得有空闲时间才得行 \手动撇嘴)

                                                                                        -----------过客 2019.10.13凌晨于香港旺角

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐