5

我处于一种情况,我需要至少付出一些努力从我的源代码中删除从未使用过的代码。一般偏好是使用静态代码分析工具。我们在其他项目中对此非常幸运,但我听到的大多数人都是从事设备级代码的 C/C++ 开发人员。

我是一名在Java EE系统上工作的 Web 开发人员。最受欢迎的分析工具是Coverity Prevent,尽管如果我能提出强有力的理由证明它更适合我们正在开发的技术,我可能会提倡其他东西。

我发现自己很怀疑——当你在一个有很多抽象的系统上运行时,静态代码分析对死代码的有效性是什么?例如,我们使用Spring的依赖注入,以及JSF。在这两种情况下,都没有简单的方法来跟踪从前端到后端的函数调用,并完整地了解什么被调用,什么没有被调用。

我非常担心死代码检查的误报将超过首先运行该工具的价值。

这种场景的经验是什么?当您的架构使用大量抽象时,您是否设法从静态代码分析工具中获得价值?您需要做些什么才能让它以最少的误报工作吗?

4

4 回答 4

4

我之前在 Coverity 工作,负责 Java 静态分析产品。

对于静态分析器来说,这种查找死代码的特殊任务可能会遇到问题。特别是对于死方法,即无法在运行时调用的方法,如果您没有进行大量调整以告知静态分析器所有动态入口点,误报率将非常高。

对于方法中的死代码,如果您的分析器具有该功能,则结果应该非常好,因为分析不会对输入数据做出任何假设。即使假设所有可能的输入,也有可能找到相关逻辑阻止采用某些分支的死代码。

于 2009-11-05T13:20:38.797 回答
2

您可以使用测试覆盖率工具(动态分析)来确定您的系统使用了哪些代码;补充是可能已经死掉的代码(它没有被执行!)并且需要检查(例如,可能有一些误报)。您对系统进行的锻炼越多,误报率就越低。

可以在此处找到可以为您收集此数据的 Java 测试覆盖率工具。

如果您想最大限度地减少误报,您可以考虑运行静态分析工具和测试覆盖率,然后取交集。

一般来说,检测死代码 X 需要证明不存在调用 X 的条件。当面对图灵机和形式的 IF 语句时,这很难(理论上是不可能的)

 if (Turing(..)) then call X();

这就是为什么静态分析工具对此有很高的误报率的原因。

然而,在许多情况下,“死代码”实际上只是无法调用它的代码(FAA 用语中的“无效代码”。)。也就是说,虽然定义了 X,但在系统中的任何地方都没有直接或间接地调用 X(或访问,如果 X 是数据项)。这些对于静态分析工具来说更容易检测到 Java 中动态类加载和反射的混乱复杂性(这使得在面对未知但可加载的类时无法解决非活动代码分析问题)。

忽略这些复杂性,可以找到静态分析工具来检测大型 Java 系统中的无效代码并报告它。这样的工具必须同时处理整个 Java 系统,否则分析中未包含的一个模块中可能存在引用。我们已经构建了一个“无效”代码检测器,并且删除器甚至可以为您提供源代码,并自动删除所有无效代码,并报告未引用的内容。您检查报告,并决定是要使用清理后的代码还是添加对明显未使用实体的访问权限。

于 2009-11-08T10:39:53.067 回答
1

在进行静态分析时,我不知道有任何静态分析工具实际上可以与抽象一起使用。您很可能必须编写一个模块来分析您使用抽象方式的过程和原因。

而且我怀疑死代码的存在成本比这更高。

于 2009-11-08T10:53:09.780 回答
0

只有在您完全了解分析过程和代码的情况下,才应在每种情况下进行静态代码分析。问题很简单,它只是粗略并提供假设。既不是解决方案,也不是完全准确的漏洞检查。您必须能够使用其他测试方法来确定误报。

静态代码分析器的价值不是代码审查。为了消除死代码,我会使用代码覆盖来分析它。- 在你的情况下 - 你提到了很多抽象......我猜静态代码分析是不够的。

于 2009-11-05T13:27:35.970 回答