【问题标题】:Effect of the Java bytecode instruction combination on the operand stackJava字节码指令组合对操作数栈的影响
【发布时间】:2013-03-19 16:08:59
【问题描述】:

对于使用 ASM 手动编写的 Java 字节码指令序列,有没有办法访问堆栈的状态?例如,对于如下组合:

ILOAD_0,ILOAD_1,IADD,DUP -> 1,1

这里的动机是编写测试代码来验证给定的一组指令是否导致给定的堆栈,例如

assert getCurrentStackLength() == 2

assert getTopElement() == (int) 1

等等。

【问题讨论】:

  • 您是在专门询问 Java 字节码,对吗?
  • 是的。 JVM 指令或 Java 字节码。
  • 所以你很想执行它?您最好的选择可能是在生成的类中的方法中生成它们,附加代码以输出堆栈的状态并运行它。然后得到结果并断言你想要断言的任何东西。
  • @JoachimSauer,我如何“输出堆栈的状态”?
  • @shail619:这是棘手的部分;-) 我从未尝试过,我认为验证和类型检查可能会使这变得困难(或不可能?)。但除了这种方法,我想不出一个纯 Java 解决这个问题(除非你想重新实现 JVM,这会带来自己的一系列问题)。

标签: java assembly bytecode


【解决方案1】:

堆栈是 JVM 的内部细节,实际上可能并不存在。

典型的 JVM 有两种操作模式 - 解释和 JIT 编译。 Interpertation 实际上模拟了堆栈和局部变量。 JIT 编译将所有内容编译为机器代码,因此不存在操作数堆栈或局部变量表之类的东西。

基本上,您要做的就是查看 JVM 的代码,找到一种方法来强制它始终解释您的代码,添加调试代码以打印出堆栈等,然后重新编译并重建所有内容.显然不是胆小的人的任务。

然而,更大的问题是您为什么要这样做。您是否尝试对 JVM 进行单元测试?您编写的任何代码都比您正在测试的代码更容易出现错误。

如果您只想找出字节码中特定点的堆栈和局部状态,那么您只需要一个静态验证器即可。那里有很多。如果你有兴趣,我已经写了one that's on Github

【讨论】:

  • 是的,我想看看。
  • 这是我写的。它是用 Python 编写的,因此可能很难从 Java 中使用。它主要用于静态分析。无论如何,如果您有任何问题,请随时提出。 github.com/Storyyeller/Krakatau
  • 感谢@Antimony。通过更详细的 JVM 文档,我发现了 StackMapTable 属性,它似乎准确地提供了我最初寻找的信息。
  • @shail,它只告诉你每个基本块开始时的状态,并且只在 51.0 和大多数 50.0 类中。它旨在帮助 JVM 加速类文件验证。
  • 我同意。但是,如果要测试的字节码组合仅限于这个“基本块”,那还没有用吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-12
  • 1970-01-01
  • 2011-12-29
  • 1970-01-01
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
相关资源
最近更新 更多