java JVM字节码验证器的职责

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10562876/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 01:34:25  来源:igfitidea点击:

Responsibilities of JVM bytecode verifier

javajvm

提问by Bober02

Could someone list major tasks that the bytecode verifier has to perform to guarantee correctness of the program? Is there a standard, minimal set of responsibilities defined in JVM specification? I was also wondering whether verifications spans across other phases such as loading and initializing.

有人可以列出字节码验证器必须执行的主要任务以保证程序的正确性吗?JVM 规范中是否定义了一组标准的、最小的职责?我还想知道验证是否跨越其他阶段,例如加载和初始化。

采纳答案by aioobe

This is specified in the JVM Specification: Chapter 4.10. Verification of class Files .

这在JVM 规范:第 4.10 章中指定类文件的验证

The bulk of the page describes the various aspects of type safety. To check that the program is type-safe the verifier needs to figure out what types of operands reside in the operand stack at each program point, and make sure that they match the type expected by the respective instruction.

大部分页面描述了类型安全的各个方面。为了检查程序是否是类型安全的,验证器需要找出每个程序点的操作数堆栈中驻留的操作数类型,并确保它们与相应指令所期望的类型相匹配。

Other things it verifies include, but is not limited to the following:

它验证的其他内容包括但不限于以下内容:

  • Branches must be within the bounds of the code array for the method.

  • The targets of all control-flow instructions are each the start of an instruction. In the case of a wide instruction, the wide opcode is considered the start of the instruction, and the opcode giving the operation modified by that wide instruction is not considered to start an instruction. Branches into the middle of an instruction are disallowed.

  • No instruction can access or modify a local variable at an index greater than or equal to the number of local variables that its method indicates it allocates.

  • All references to the constant pool must be to an entry of the appropriate type. (For example, the instruction getfield must reference a field.)

  • The code does not end in the middle of an instruction.

  • Execution cannot fall off the end of the code.

  • For each exception handler, the starting and ending point of code protected by the handler must be at the beginning of an instruction or, in the case of the ending point, immediately past the end of the code. The starting point must be before the ending point. The exception handler code must start at a valid instruction, and it must not start at an opcode being modified by the wide instruction.

  • 分支必须在方法的代码数组范围内。

  • 所有控制流指令的目标都是指令的开始。在宽指令的情况下,宽操作码被认为是指令的开始,并且给出被该宽指令修改的操作的操作码不被认为是指令的开始。不允许进入指令中间的分支。

  • 没有指令可以访问或修改索引大于或等于其方法指示分配的局部变量数的局部变量。

  • 对常量池的所有引用都必须指向适当类型的条目。(例如,指令 getfield 必须引用一个字段。)

  • 代码不会在指令的中间结束。

  • 执行不能脱离代码的末尾。

  • 对于每个异常处理程序,受处理程序保护的代码的起始点和结束点必须位于指令的开头,或者在结束点的情况下,紧接在代码末尾之后。起点必须在终点之前。异常处理程序代码必须从有效指令开始,并且不能从被宽指令修改的操作码开始。

As a final step the verifier also performs a data-flow analysis, which makes sure that no instruction reference any uninitialized local variables.

作为最后一步,验证器还执行数据流分析,以确保没有指令引用任何未初始化的局部变量。

回答by Edwin Dalorzo

Alternatively you might like to give it a look at the Java Language Environmentwhite paper by James Gosling.

或者,您可能想看看James Gosling的Java Language Environment白皮书。

![enter image description here

![在此处输入图片说明

The bytecode verifier traverses the bytecodes, constructs the type state information, and verifies the types of the parameters to all the bytecode instructions.

The illustration shows the flow of data and control from Java language source code through the Java compiler, to the class loader and bytecode verifier and hence on to the Java virtual machine, which contains the interpreter and runtime system. The important issue is that the Java class loader and the bytecode verifier make no assumptions about the primary source of the bytecode stream--the code may have come from the local system, or it may have travelled halfway around the planet. The bytecode verifier acts as a sort of gatekeeper: it ensures that code passed to the Java interpreter is in a fit state to be executed and can run without fear of breaking the Java interpreter. Imported code is not allowed to execute by any means until after it has passed the verifier's tests. Once the verifier is done, a number of important properties are known:

  • There are no operand stack overflows or underflows
  • The types of the parameters of all bytecode instructions are known to always be correct
  • Object field accesses are known to be legal--private, public, or protected

While all this checking appears excruciatingly detailed, by the time the bytecode verifier has done its work, the Java interpreter can proceed, knowing that the code will run securely. Knowing these properties makes the Java interpreter much faster, because it doesn't have to check anything. There are no operand type checks and no stack overflow checks. The interpreter can thus function at full speed without compromising reliability.

字节码校验器遍历字节码,构造类型状态信息,校验所有字节码指令的参数类型。

该图显示了从 Java 语言源代码通过 Java 编译器到类加载器和字节码验证器,再到 Java 虚拟机(包含解释器和运行时系统)的数据和控制流。重要的问题是 Java 类加载器和字节码验证器不对字节码流的主要来源做出任何假设——代码可能来自本地系统,或者它可能已经绕地球半个地球运行。字节码验证器充当一种看门人:它确保传递给 Java 解释器的代码处于适合执行的状态,并且可以运行而不必担心破坏 Java 解释器。在通过验证者的测试之前,不允许以任何方式执行导入的代码。一旦验证完成,

  • 没有操作数堆栈上溢或下溢
  • 已知所有字节码指令的参数类型总是正确的
  • 已知对象字段访问是合法的——私有的、公共的或受保护的

虽然所有这些检查看起来非常详细,但当字节码验证器完成其工作时,Java 解释器可以继续进行,因为知道代码将安全运行。了解这些属性会使 Java 解释器更快,因为它不需要检查任何东西。没有操作数类型检查和堆栈溢出检查。因此,解释器可以全速运行而不会影响可靠性。

回答by mprivat

It does the following:

它执行以下操作:

  • There are no operand stack overflows or underflows
  • The types of the parameters of all bytecode instructions are known to always be correct
  • Object field accesses are known to be legal--private, public, or protected
  • 没有操作数堆栈上溢或下溢
  • 已知所有字节码指令的参数类型总是正确的
  • 已知对象字段访问是合法的——私有的、公共的或受保护的

Reference: http://java.sun.com/docs/white/langenv/Security.doc3.html

参考:http: //java.sun.com/docs/white/langenv/Security.doc3.html