您将如何进行 C/C++ 代码中的死代码检测?我有一个相当大的代码库可供使用,并且至少 10-15% 是死代码。有没有基于 Unix 的工具来识别这个区域?有些代码仍然使用大量预处理器,自动化流程可以处理吗?

有帮助吗?

解决方案

您可以使用代码覆盖率分析工具,并在代码中查找未使用的位置。

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

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

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

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

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

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

其他提示

在 gcc 下使用 -Wunreachable-code 进行编译。

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

此 CERT 通报列出了一些其他用于静态死代码检测的工具

您的方法取决于可用性(自动)测试。如果您拥有一个您信任的测试套件来覆盖足够的功能,您可以使用覆盖率分析,如前面已经建议的答案。

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

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

如果这对您没有足够的帮助,并且您特别想找到与预处理器相关的死代码,我建议您发布有关代码的更多详细信息。例如,如果它主要与#ifdef设置的各种组合相关,您可以编写脚本来确定(组合)设置并找出从未实际构建的组合等。

g ++ 4.01 -Wunreachable-code警告函数中无法访问的代码,但不会警告未使用的函数。

int foo() { 
    return 21; // point a
}

int bar() {
  int a = 7;
  return a;
  a += 9;  // point b
  return a;
}

int main(int, char **) {
    return bar();
}

g ++ 4.01将发出关于b点的警告,但对foo()(点a)一无所知,即使它在此文件中无法访问。虽然令人失望,但这种行为是正确的,因为编译器无法知道函数foo()在某些其他编译单元中未被声明为extern并从那里调用;只有链接器才能确定。

仅适用于C代码并假设整个项目的源代码 如果可用,请使用开源工具 Frama-C 启动分析。 在GUI中显示红色的程序的任何声明都是 死代码。

如果你有“死代码”问题,你可能也有兴趣 删除“备用代码”,执行但不执行的代码 有助于最终结果。这需要你提供 准确的I / O功能模型(你不会想要的 删除看似“备用”的计算但 用作 printf 的参数。 Frama-C有一个指出备用代码的选项。

Mozilla Open Office 拥有自行开发的解决方案。

这样的死代码分析需要对整个项目进行全局分析。您无法通过单独分析翻译单元来获取此信息(如果它们完全位于单个翻译单元中,您可以检测到死实体,但我认为这不是您真正想要的)。

我们已经使用我们的DMS软件重新设计工具包来实现Java代码的完全实现,通过一次解析所涉及的所有编译单元,为所有内容构建符号表并追踪所有引用。没有引用且没有声称是外部API项的顶级定义已经死亡。此工具还会自动删除死代码,最后您可以选择所需内容:死实体的报告或剥离这些实体的代码。

DMS还用各种方言解析C ++(EDIT 2014年2月:包括MS和GCC版本的C ++ 14 [编辑2017年11月:现在C ++ 17] )并构建所有必要的符号表。从那时起,追踪死亡参考将是直截了当的。 DMS也可用于剥离它们。请参阅 http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html

Bullseye 覆盖工具会有所帮助。但它不是免费的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top