14

对不同级别的代码执行静态分析的各种权衡是什么?例如对于 Java,为什么有人会对 Java 源代码、Jasmin代码和 Java 字节码进行静态分析?选择是否限制或扩展了能够进行的各种类型的分析?选择是否影响分析的正确性?谢谢。

4

4 回答 4

4

对不同级别的代码执行静态分析的各种权衡是什么?以 Java 为例,为什么有人会对 Java 源代码和 Java 字节码进行静态分析?

用户的角度来看,我想说的是,除非您有非常具体、易于形式化的要分析的属性(例如纯安全属性),否则请使用支持 Java 源代码的工具。

从工具开发人员的角度来看,使用一个或另一个级别可能更容易。我在这里介绍我想到的差异。(请注意,使用编译器和/或体面的反编译器,例如工具在一层上运行并将结果呈现在另一层上。)

Java源代码的优点:

  • 结构化语言,即循环等,而不是任意跳转。(例如,这使得创建最弱的前置条件演算变得容易得多。)
  • 您可以在代码中做出更多假设(字节码程序更具表现力)。

字节码的优点:

  • 语言规范(字节码指令的语义)要简单得多。
  • 机器(VM)的更“固定”规范
  • 您可以将分析扩展到遗留代码和库。
  • 分析允许针对 JVM 的其他语言(Closure、Scala、JRuby...)
  • 不需要可能复杂的解析器

机器码的优点:

  • 您验证您实际为 CPU 提供的内容。(如果您想要完全验证的链,则无需使用经过验证的编译器或经过验证的 VM。)

最先进的工具,如Spec#等(C# 的形式方法方言)通常通过专门为形式分析设计的中间语言(在 Spec# 案例中为 BoogiePL(更接近 MSIL 或 C#))。

选择是否限制或扩展了能够进行的各种类型的分析?

最后......不,不是真的。无论您选择分析哪种(图灵完备)语言,您都面临着相同的基本问题。根据您分析的属性,YMMV。

如果您使用正式方法并考虑自己实施分析,我怀疑您会找到更好的字节码工具支持。如果您是用户开发人员并希望对自己的代码库进行分析,我怀疑您将从在 Java 源代码级别运行的工具中受益更多。

选择是否影响分析的正确性?

取决于您所说的正确性。静态分析通常是“防御性的”,因为您不会假设您不知道的任何事情都是真实的。如果你只关注健全的验证系统,所有这些都将“同样正确”。

于 2011-10-26T10:47:33.300 回答
1

IntelliJ 对字节码中不可用的注释(例如 Javadoc 和参数名称)进行静态分析。例如拼写错误和名称不一致。代码分析可确保您在任何问题的行内都有行号和位置。

分析字节码的好处是它更简单,可能就是你所需要的。你可能有行号,但你不会有位置。并且您可以分析您没有源代码的已编译代码,例如库。

于 2011-10-26T10:52:17.330 回答
1

对不同级别的代码执行静态分析的各种权衡是什么?例如对于 Java,为什么有人会对 Java 源代码、Jasmin 代码和 Java 字节码进行静态分析?

这样想吧。如果你从 Jasmin 或字节码中得到负面结果(表明或暗示负面或有害属性的结果),你会怎么做?您将如何以及时且具有成本效益的方式解决这个问题?

现在考虑对源代码(很可能是您的源代码或您拥有的代码)的静态分析返回报告需要解决的负面/有害属性的情况?

你认为解决这个映射到源代码的有害方面会比处理有害方面(可能相似或相关)但这次映射到字节码或 Jasmin 更难吗?

问题是 1) Jasmin 应该是合法字节码的一对一表示,以及 2) 字节码是由真正的编译器生成的。在表现良好的编译器存在的情况下,字节码中的问题直接映射到源代码中引入的问题的可能性非常小。

无论在字节码级别检测到的问题是由于源代码级别引入的问题还是错误编译器/环境的结果,这些问题通常是不可操作的(sp?)。您通常不能对其采取行动,至少不能直接采取行动。

在源代码级别检测到的问题,OTH,它们是有效的可操作的。也就是说,您可以亲自动手并修复它们(并通过推断,消除从前者派生的字节码的任何问题。)

有些事情可以在字节码级别检测到,特别是在打包的上下​​文中(即打包不必要的库。)但是您几乎不需要在字节码级别进行验证。

除非您从事编译器和语言设计业务(在这种情况下针对 VM),否则出于效率和实用性的目的,1)您假设编译器是正确的,并且 2)鉴于指定 JVM 的方式,您还假设编译器在编译时执行验证,JVM 在运行时执行验证。

选择是否限制或扩展了能够进行的各种类型的分析?选择是否影响分析的正确性? 谢谢。

你如何定义正确性?在这种情况下,正确性是什么?它如何影响正确性?我们是在类型系统级别谈论正确性吗?部分和/或完全正确?关于公平、活泼等属性的正确性?分析过程本身的正确性?满足一项或多项要求的正确性?

定义你的条款老兄:)

无论如何,您必须假设编译器正在将您的代码充分正确地转换为目标指令集(同样,除非您从事编译器/语言设计业务。)

如果您假设您的代码的“本机”表示是正确的(即,它根据所需的目标平台和类型系统“映射”到它),那么您将验证领域缩小到您的源要验证的属性的代码。

于 2011-10-26T14:50:07.100 回答
1

另一个考虑因素是“抽象会丢失高级信息”。我们正在使用源代码(高级)来做,因为我们需要在源代码中出现表达式。

源代码到二进制文件的映射在源代码可视化领域非常重要。

于 2012-03-23T07:20:31.363 回答