2026年clang-callgraph 调用链工具使用

clang-callgraph 调用链工具使用clang callgraph 是一个辅助分析代码的 python 包 可以分析 C C 函数的调用链 反向调用链 这个库是我从 Vermeille clang callgraph fork 而来 原作者在最近的 issue 13 里说不再维护 所以才 fork 了一份 自己增加和维护一些功能 目前出于自己的日常使用目录和爱好进行维护 一定也还有非常多的不足之处 调用链的展示方式是参考的

大家好,我是讯享网,很高兴认识大家。这里提供最前沿的Ai技术和互联网信息。



clang-callgraph 是一个辅助分析代码的 python 包,可以分析 C/C++ 函数的调用链、反向调用链。这个库是我从 Vermeille/clang-callgraph fork 而来,原作者在最近的 issue#13 里说不再维护,所以才 fork 了一份,自己增加和维护一些功能。目前出于自己的日常使用目录和爱好进行维护,一定也还有非常多的不足之处。

调用链的展示方式是参考的 @satanson 设计的 calltree.pl,这个大佬设计的工具美感很强,但是会在当前目录下生成很多缓存文件,而且命令参数有点难记,我也 fork 了一份尝试修改成交互式的,但是因为是用 Perl 写的,实在是看不懂,所以作罢。不过对于需要分析 C++ 代码的读者,还是强烈推荐使用,功能强大,而且工具的输出审美水平很高。作者写的教程为 C++阅码神器cpptree.pl和calltree.pl的使用。

clang-callgraph 项目地址:

github.com/LiuYinCarl/c

目前主要的改动包括:

  • 集成 readline,支持了 Tab 自动补全。
  • 集成 pygments,支持函数颜色展示,其实可以支持配置代码主题,但是先暂缓吧。
  • 支持查询调用链、可通过配置关键字来只搜寻部分调用链或者忽略部分调用链,使得调用链更清晰。
  • 支持查询反向调用链、比如函数调用链如下 A -> B -> C,那么输入 C,可以反向展示 C -> B -> A 的反向调用链。
  • 支持交互式查询,类似 RedisCPython 等的交互式查询。
  • 支持只展示指定多少调用层级的调用链。
  • 支持源码修改后更新调用链(这个目前拉了一个分支做了一个 demo,不过优先级不高,而且要处理多线程问题,慢慢做吧)。

这个包主要需要安装 libclang-14,以 Ubuntu 系统为例来进行安装,其他 Linux 操作系统方法差不多。

# 安装依赖库 $ sudo apt install libclang-14-dev

安装 Python 依赖库

$ pip3 install clang==14

下载并安装 clang-callgraph 包

需要注意,如果提示 clang-callgraph 没有被安装到系统路径,那么改一下 PATH

增加 clang-callpath 的安装目录到 PATH 就好

\( git clone https://github.com/LiuYinCarl/clang-callgraph.git \) cd clang-callgraph $ pip3 install . ​

下载 skynet 源码库并且编译,这里我们使用 bear 这个工具生成

compile_commands.json,clang-callgraph 需要这个文件来梳理

项目的调用图

\( git clone https://github.com/cloudwu/skynet.git \) bear – make linux ​

进入 skynet 的源码库,使用 clang-callgraph

$ clang-callgraph ./compile_commands.json

这个包主要是使用 libclang 来解析 C/C++ 代码,然后利用解析出来的代码抽象语法树信息来构建调用图和引用图。这里需要特别注意,因为这里使用的是 libclang-14, 所以一些使用了比较新的 C/C++ 语法的源代码可能不能很好的进行分析,需要考虑升级一下这个库,不过我目前主要用 clang-callgraph 来分析一些 C 语言的项目,如 CPython, Lua, skynet 等,所以暂时没有升级动力。

为了避免和函数名有冲突,所以 clang-callgraph 的命令都是以特殊字符开头,目前支持 4 种指令。

  • @ 开头的指令是命令指令,主要用来设置一些参数,例如 @ filter error info 就是新增两个过滤关键字 errorinfo
  • ?开头的指令是调用链(过滤版本)查询,如果通过 @ filter error info 设置了 errorinfo 关键字,那么 ? main() 这条指令就只会查询从 main() 函数开始,到包含 error 或者 info 关键字的函数为止的调用链。
  • 开头的指令是调用链(忽略版本)查询,如果通过 @ ignore error info 设置了 errorinfo 关键字,那么 ! main() 这条指令就是查询从 main() 函数开始,且调用链中不包含 errorinfo 关键字的所有调用链。
  • & 开头的指令是反向调用链查询,? exit(int) 指令就是查询 exit(int) 这个函数的反向调用链。 目前暂时不支持关键字过滤和忽略(主要是感觉没什么用)。

以上面安装的 skynet 为例,来看一下 clang-callgraph 的实际使用

首先设置下只展示三层调用链。

接着查看一下所有以 main 开头的函数,这里查询完成之后,查询结果会缓存到系统中,下次重新查询函数列表前就可以使用 Tab 对这些查询结果进行补全。

查看 main(int, char ) 的调用图,这里可以用 Tab 进行补全。

结果比较多,所以我们重新设置一下,只看 1 层调用链。

接着介绍一下过滤功能,这个功能可以让我们只专注于 函数 A 到 函数 B 的调用链。假设我们只想关注从 main 函数到 skynet_context_dispatchall 函数的调用,那么我们按照如下指令进行查询。

可以看到,调用链非常的清晰。

和这个类似的是忽略功能,这个功能的使用场景是,希望研究函数 A 的所有调用链,但是希望忽略掉里面日志,告警等一些不重要的函数。使用方法如下。

最后介绍一下反向调用链查询工具,这个功能的使用场景是,你正在研究函数 A,希望知道函数 A 在哪些调用路径中被最终调用到了。比如我们希望知道在 skynet 中 skynet_handle_retire(uint32_t) 会在哪些场景中被最终调用到。

考虑到 skynet 很多人不是很熟悉,那么我们使用 clang-callgraph 研究一下 CPython 中列表的创建过程吧。因为 clang-callgraph 是用 Python 写的,会比较慢,所以对于一些大型项目,建议先设置一下最大调用链深度,并且设置忽略一些非常频繁的关键字。下面是示例。

觉得有帮助或者有启发的话,请点一个 star 吧!
github.com/LiuYinCarl/c


小讯
上一篇 2026-04-07 08:10
下一篇 2026-04-07 08:08

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/219598.html