JVM 如何验证在装入类时是否存在潜在的操作数堆栈溢出?

2022-09-03 06:53:31

回顾一些演示,我遇到了以下声明:当JVM加载一个类时,它可以分析其内容并确保操作数堆栈没有溢出或下溢。我发现很多来源都提出了相同的主张,但没有具体说明它是如何完成的。

我不清楚如何使用静态分析进行这种验证。假设我有一个(恶意的)方法,它获取一些值作为参数,并使用它来执行一系列弹出。在加载时,迭代次数是未知的,因为它取决于方法调用方给出的参数。因此,在我看来,只有在运行时才能确定是否会有下溢。我在这里错过了什么?


答案 1

您可以在 Java 虚拟机规范中找到字节码验证程序的基本描述。

简单来说,每个分支点的堆栈深度都是已知的,并且在同一合并点合并的两个执行路径也必须具有相同的堆栈深度。因此,验证器将不允许您在没有相应放置的情况下执行一系列弹出。


答案 2

该方法的代码被拆分为多个执行块。“块”是一系列指令,可以在不跳出或跳入的情况下执行。这些块构建所有可能的执行路径的有向图。

一个块总是期望在其开始时有一定的堆栈大小,并且在其末尾有一个固定的堆栈大小(开始+所有推送 - 所有弹出)。验证程序检查对于可以从给定块“b”到达的所有块“a”,b的结束堆栈大小与a的起始堆栈大小匹配。


推荐