在源代码,字节代码,机器代码等上执行静态分析有哪些权衡?

时间:2011-10-26 10:43:59

标签: java bytecode static-code-analysis

对各种代码级别执行静态分析有哪些权衡取舍?例如,对于Java,为什么有人会对Java源代码与Jasmin代码与Java字节码进行静态分析?选择是否限制或扩展了可以进行的各种类型的分析?选择是否会影响分析的正确性?感谢。

4 个答案:

答案 0 :(得分:5)

  

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

用户的角度来看,除非你有一个非常具体的,易于形式化的属性来分析(比如纯安全属性),否则请使用支持Java源代码的工具。

从工具开发人员的角度来看,使用一个级别或另一个级别可能更容易。我在这里介绍了我脑海中的不同之处。 (请注意,使用编译器和/或体面的反编译器,工具可以在一个层上运行,并将结果显示在另一个层上。)

Java源代码优点:

  • Structured language,即循环等,而不是任意跳转。 (例如,这使得创建weakest precondition微积分变得容易得多。)
  • 您可以在代码中做出更多假设(字节码程序更具表现力)。

字典的优点:

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

机器代码优点:

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

最先进的工具,如Spec#等(C#的形式方法)通常会通过中间语言(规范#案例中的BoogiePL(更好的MSIL和C#))专为正式分析而设计。

  

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

最后......不,不是真的。无论您选择分析哪种(Turing complete)语言,您都会面临同样的基本问题。取决于您分析的属性,YMMV虽然。

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

  

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

取决于你的正确性。静态分析通常是“防御性的”,因为你不会假设任何你不知道的事情是真的。如果您将注意力限制在sound验证系统,则所有系统都将“同样正确”。

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

  

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

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

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

你是否认为你将更难以解决这个有害方面被映射到源代码而不是对有害方面(可能类似或相关)做同样但这次映射到字节码还是Jasmin?

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

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

在源代码级别检测到的问题,OTH,它们可以有效地操作。也就是说,你可以抓住它并修复它们(并通过推断,从前者派生的字节代码中删除任何问题。)

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

除非您从事编译器和语言设计(在这种情况下针对VM​​),为了提高效率和实用性,1)您认为编译器是正确的,并且2)给出了JVM规范的方式' ed,您还假设编译器在编译时执行验证,JVM在运行时进行验证。

  

选择是否限制或扩展了各种类型的分析   要做什么? 选择是否会影响分析的正确性?   感谢。

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

定义你的术语dude:)

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

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

答案 3 :(得分:1)

另一个考虑因素是'抽象将失去高水平的信息'。 我们正在使用源代码(高级),因为我们需要在源代码中出现表达式。

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