传统C/C++项目中的死代码检测

Naz*_*gob 68 c++ automation static-analysis legacy-code dead-code

您如何在C/C++代码中进行死代码检测?我有一个非常大的代码库可供使用,至少10-15%是死代码.有没有基于Unix的工具来识别这个区域?有些代码仍然使用了很多预处理器,可以自动化处理吗?

Joh*_*han 30

您可以使用代码覆盖率分析工具来查找代码中未使用的位置.

gcc工具链的一个流行工具是gcov,以及图形前端lcov(http://ltp.sourceforge.net/coverage/lcov.php).

如果使用gcc,则可以使用gcov支持进行编译,该支持由'--coverage'标志启用.接下来,运行您的应用程序或使用此gcov启用的构建运行您的测试套件.

基本上gcc会在编译期间发出一些额外的文件,应用程序也会在运行时发出一些覆盖数据.您必须收集所有这些(.gcdo和.gcda文件).我不会在这里详细介绍,但您可能需要设置两个环境变量以便以合理的方式收集覆盖率数据:GCOV_PREFIX和GCOV_PREFIX_STRIP ...

运行后,您可以将所有覆盖数据放在一起,并通过lcov工具包运行它.虽然有点涉及,但也可以合并来自不同测试运行的所有覆盖文件.

无论如何,你最终得到了一组很好的网页,显示了一些覆盖信息,指出了没有覆盖的代码片段,因此没有被使用.

当然,您需要仔细检查代码的各个部分是否在任何情况下都没有使用,并且很大程度上取决于您的测试在多大程度上运用代码库.但至少,这将给出关于可能的死码候选者的想法......


Ste*_*sop 17

使用-Wunreachable-code在gcc下编译它.

我认为版本越新越好,你会得到更好的结果,但我的印象可能是错误的,这是他们一直在积极研究的.请注意,这会进行流分析,但我不相信它会告诉您"离开预处理器时已经死亡的"代码,因为它从未被编译器解析过.它也不会检测例如从未被调用的导出函数,或者特殊情况处理代码,这恰好是不可能的,因为没有任何东西用该参数调用函数 - 你需要代​​码覆盖(并运行功能测试,而不是单元测试.假设单元测试具有100%的代码覆盖率,因此就应用程序而言,执行"死"的代码路径.尽管如此,考虑到这些限制,这是一种简单的方法来开始在代码库中找到最完整的bollixed例程.

此CERT顾问列出了一些其他静态死代码检测工具

  • 但是,如果您的代码没有使用新功能,您仍然可以使用旧的gcc作为静态分析工具.所以我的回答并非完全错误.有点触及,我知道;-) (3认同)
  • 这个答案对于从gcc中删除了-Wunreachable-code选项这一事实不再有效.http://gcc.gnu.org/ml/gcc-help/2011-05/msg00360.html (2认同)

and*_*ykx 5

您的方法取决于可用性(自动化)测试。如果您有一个测试套件,您相信它可以涵盖足够数量的功能,那么您可以使用覆盖分析,正如之前的答案已经建议的那样。

如果您不是那么幸运,您可能想研究源代码分析工具,如SciTools 的“理解”,它可以帮助您使用大量内置分析报告分析您的代码。我使用该工具的经验可以追溯到 2 年前,所以我不能给你太多细节,但我记得的是,他们提供了令人印象深刻的支持,错误修复和问题答案的周转时间非常快。

我找到了一个关于静态源代码分析的页面,其中还列出了许多其他工具。

如果这也不能充分帮助您,并且您对找出与预处理器相关的死代码特别感兴趣,我建议您发布有关代码的更多详细信息。例如,如果它主要与#ifdef 设置的各种组合有关,您可以编写脚本来确定(组合)设置并找出哪些组合从未真正构建过,等等。


Max*_*ert 5

双方的Mozilla开放式办公有本土的解决方案。

  • 我已将博客文章的第一个链接切换到(希望更持久)文档页面。Open Office 链接似乎有效。 (2认同)

Pas*_*uoq 5

仅针对 C 代码并假设整个项目的源代码可用,使用开源工具Frama-C启动分析。在 GUI 中显示红色的任何程序语句都是死代码。

如果您有“死代码”问题,您可能还想删除“备用代码”,即已执行但对最终结果没有贡献的代码。这要求您提供 I/O 函数的准确模型(您不希望删除看似“备用”但用作 的参数的计算printf)。Frama-C 有一个用于指出备用代码的选项。