为C代码生成调用图

8

我正在编写一个工具,需要为一些C项目生成调用图(callgraph)。

我已经可以使用clang为一个文件生成调用图,但是我不知道如何在整个包含数十个头文件和源文件的项目中生成调用图。

任何能够生成可解析文件的调用图工具都可以,如果有可用的库会更好。


通过函数指针的间接调用可能会使这个任务变得困难。对于其他调用,创建汇编代码并处理它,将是使用自编写脚本实现的一种方式。 - MvG
1
你已经有一个doxygen标签了 - 我相信它可以将调用图以XML格式导出... 你知道吗?如果知道,你能解释一下它对你的目的有什么问题吗? - Tony Delroy
@MvG 这看起来是个不错的想法。 - cipher
@Tony 是的,我知道它可以生成XML文件,但我想知道是否有Doxygen提供的库可以用来自动化此过程,而无需用户打开Doxygen并自行生成文件。 - cipher
还有一个想法:ld --gc-sections 也必须进行某种调用图分析。不确定是否可以钩入其中,但可能有办法。它可能无法真正处理间接调用,但它可能能够决定何时某些代码获取函数地址以便稍后调用。 - MvG
@cipher:Doxygen可以作为命令行实用程序运行 - 您可以提供正确的配置并使用system()...不需要用户参与,也不需要打开GUI。 - Tony Delroy
2个回答

4
值得一提的是,优秀的GNU cflow
GNU cflow分析一组C源文件并打印一个图表,记录程序中的控制流。
GNU cflow能够为C源代码生成直接和反转的流程图。可以选择生成交叉引用列表。两种输出格式已经实现:POSIX和GNU(扩展)。在分析之前,还可以对输入文件进行预处理。
编辑: 至于库请求。您可能想要“调整” output.c 并且不是打印数据,而是使用其他方式处理数据。内部流已组织到输出处理程序中,因此编写自己的处理程序可能已经解决了问题。 但它需要一些努力。

2

将我的评论转化为答案。

您可以查看汇编输出并使用脚本处理。假设在Linux上使用gcc,您需要向gcc传递-S标志,并使用以下类似的内容处理结果:

perl -ne '/^([^. \t#].*):/ and $f=$1;/call\s+([^*]\S*)/ and print "$f -> $1\n";' *.S

这将为您提供每个静态调用的行,包括调用和被调用的函数。您可以在其周围添加一些样板代码,并将结果提供给dot或其他您想要处理它的工具。您可以省略正则表达式中“不得以星号开头”的部分,以获得一些间接调用的指示。您仍然无法确定在该点将调用哪些函数,但至少您会知道还有更多需要了解的内容。

正如您所指出的那样,这并不能处理间接函数调用。 - Ira Baxter
3
@IraBaxter,给我任何声称可以处理间接函数调用的解决方案,而不需要运行应用程序并记录实际调用,我将编写一个调用该工具无法预测的应用程序。C指针就像黑魔法一样,你可以用它们做任何事情。 - MvG
每当您为代码构建静态分析器时,您得到的结果在准确性上是有限的;这不仅仅是指针,而是因为您正在处理图灵机。是的,您几乎总是可以欺骗它。对于大多数代码,您可以获得相当合理的答案,否则没有人会使用静态分析工具。去了解一下“保守流分析”。 - Ira Baxter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接