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

CodeViz是由Mel Gorman开发的用于分析C/C++源代码中函数调用关系的工具,它通过GCC补丁生成call graph,并使用Graphviz绘制。本文介绍了如何在Windows+Cygwin环境下配置和使用CodeViz,以及分析《嵌入式实时操作系统 uC/OS-II》范例程序的过程,展示如何通过逐步细化生成清晰的函数调用图,以辅助理解代码结构。
AI助手已提取文章相关产品:

CodeViz是《Understanding The Linux Virtual Memory Manager》(at Amazon下载地址在页尾)的作者 Mel Gorman 写的一款分析C/C++源代码中函数调用关系的open source工具(类似的open source软件有 egyptncc)。其基本原理是给 GCC 打个补丁,让它在编译时每个源文件时 dump 出其中函数的 call graph,然后用 Perl 脚本收集并整理调用关系,转交给Graphviz绘制图形。

CodeViz 原本是作者用来分析 Linux virtual memory 的源码时写的一个小工具,现在已经基本支持 C++ 语言,最新的 1.0.9 版能在 Windows + Cygwin 下顺利地编译使用:)。需要注意的是:1) 下载 GCC 3.4.1 的源码 gcc-3.4.1.tar.gz 放到 codeviz-1.0.9/compilers,2) 安装 patch 程序(属于Utils类),3) 从 http://www.graphviz.org 下载并安装 Graphviz 2.6。

我用 CodeViz 分析《嵌入式实时操作系统 uC/OS-II (第二版)》中的第一个范例程序,步骤如下:

1. 想办法让 gcc 能编译uC/OS 2.52和范例程序的源码,每个C源文件生成对于的.c.cdepn文件。只要编译(参数 -c)就行,无需连接。

2. 调用genfull生成full.graph,这个文件记录了所有函数在源码中的位置和它们之间的调用关系。

3. 使用gengraph生成我关心的函数的调用关系。

首先分析main():

1. gengraph --output-type gif -f main
分析main()的call graph,得到的图如下,看不出要领:

2. gengraph --output-type gif -f main -s OSInit
暂时不关心OSInit()的内部实现细节(参数 -s),让它显示为一个节点。得到的图如下,有点乱,不过好多了:

3. gengraph --output-type gif -f main -s OSInit -i "OSCPUSaveSR;OSCPURestoreSR"
基本上每个函数都会有进入/退出临界区的代码,忽略之(参数 -i)。得到的图如下,基本清楚了:

4. gengraph --output-type gif -f main -s "OSInit;OSSemCreate" -i "OSCPUSaveSR;OSCPURestoreSR" -k
OSSemCreate()的内部细节似乎也不用关心,不过保留中间文件sub.graph(参数 -k),得到的图如下,

5. dot -Tgif -o main.gif sub.graph
修改sub.graph,使图形符合函数调用顺序,最后得到的图如下,有了这个都不用看代码了:)

接着分析OSTimeDly()的被调用关系

gengraph --output-type gif -r -f OSTimeDly

看看哪些函数调用了OSTimeDly(),参数 -r ,Task()和TaskStart()都是用户编写的函数:

最后看看Task()直接调用了哪些函数:

gengraph --output-type gif -d 1 -f Task

只看从Task出发的第一层调用(参数 -d 1):

在分析源码的时候,把这些图形打印在手边,在上面做笔记,实在方便得很。

您可能感兴趣的与本文相关内容

<think>嗯。。。用户这次想了解如何绘制函数调用关系图。结合之前的引用内容,看来用户可能是个开发者,正在处理代码重构或项目分析的工作。 从引用材料看,用户似乎关注Python和C++语言的解决方案。引用[1]提到python call graph工具,引用[2]讲VScode的流程图绘制,引用[3]推荐Doxygen+Graphviz组合,引用[4]涉及pycallgraph——这些正好构成完整的回答框架。 用户上次询问的是代码可视化工具,这次更聚焦于函数调用关系的呈现。ta应该需要具体可操作的方案,而不是理论说明。考虑到开发者群体的习惯,回复要突出实用性和技术细节。 注意到引用[3]的Doxygen方案虽然强大但配置复杂,可能更适合大型项目;而引用[2]的VSCode方案上手快但功能有限。需要帮用户区分使用场景:小范围快速查看选VSCode或pycallgraph,全项目文档生成选Doxygen。 准备在回复中结构化呈现四种方案:首推pycallgraph和Doxygen两个专业工具,补充VSCode手动绘制作为灵活选项,最后提醒可视化插件这种轻量级方案。每个方法都给出核心步骤,避免用户二次搜索。 用户没说明语言环境,但引用多次出现Python,所以把Python方案放在前面。最后生成的提问要引导用户补充关键信息,比如项目规模和语言类型——这对推荐工具很重要。 </think>根据你的需求,绘制函数调用关系图主要有以下几种高效方法,结合引用内容整理如下: --- ### 一、Python专属工具 1. **pycallgraph**(引用[4]) - 安装:`pip install pycallgraph` - 使用示例: ```python from pycallgraph import PyCallGraph from pycallgraph.output import GraphvizOutput with PyCallGraph(output=GraphvizOutput()): # 执行你的函数 your_function() ``` - 输出:自动生成函数调用关系的`.png`文件 - 优点:无需手动分析代码,动态跟踪执行过程 2. **静态代码分析工具**(引用[1]) - 如`pyan3`或`code2flow` - 命令示例:`pyan3 your_script.py --uses --dot > call_graph.dot` - 配合Graphviz生成图片:`dot -Tpng call_graph.dot -o output.png` --- ### 二、跨语言方案 1. **Doxygen + Graphviz**(引用[3]) - **安装**: - Doxygen:官网下载安装 - Graphviz:独立安装并配置环境变量 - **配置步骤**: 1. 运行`doxywizard`生成配置文件 2. 启用选项: ``` EXTRACT_ALL = YES CALL_GRAPH = YES CALLER_GRAPH = YES HAVE_DOT = YES ``` 3. 指定代码路径并生成文档 - **输出**:生成包含函数调用图的HTML文档 - 适用语言:C++/Java/Python等20+语言 2. **VSCode手动绘制**(引用[2]) - 安装插件:`Draw.io Integration` - 操作流程: 1. 新建`.drawio`文件 2. 用矩形框表示函数/类 3. 用箭头标注调用关系 - 适用场景:少量函数的快速草图 --- ### 三、轻量级可视化 - **IDE内置工具** - PyCharm:右键函数 → `Diagrams → Show Diagrams` - VSCode:安装`CodeViz`或`Graphviz Preview`插件 --- ### 总结对比 | 方法 | 自动化程度 | 适用规模 | 语言支持 | |-------------------|------------|------------|--------------| | pycallgraph | ★★★★☆ | 中小项目 | Python | | Doxygen+Graphviz | ★★★★★ | 大型项目 | 多语言 | | VSCode手动绘制 | ★☆☆☆☆ | 少量函数 | 任意语言 | | IDE内置工具 | ★★★☆☆ | 中等项目 | 依赖IDE支持 | > 提示:大型项目首选Doxygen+Graphviz;快速调试Python代码推荐pycallgraph;临时草图可用VSCode手动绘制[^1][^2][^3][^4]。 ---
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值