在我的字节码检测项目中,我经常偶然发现 VerifyErrors。但是,默认的 java Verifier 几乎没有提供有关哪条指令导致错误的信息(它只提供方法和一条小消息)。是否有任何独立的字节码验证器可以提供更高级的帮助来定位错误,至少是精确的指令位置?谢谢你。
3 回答
ASM CheckClassAdaptor.verify() 给出了很好的反馈: http ://asm.ow2.org/
我也在寻找可以报告潜在验证错误的东西,尤其是IncompatibleClassChangeError
s。我编写了一个小测试项目,其中有一个 API 类和另一个调用 API 方法的客户端类,以及一个运行验证程序的主类;然后更改 API,重新编译它而不是客户端,并检查可以捕获的内容。-target 7
尽管目前没有特殊的 JDK 7 功能,但已使用。
首先也是最明显的,Class.forName
可以在客户端类的签名中发现某些错误,但它似乎不会检查方法体是否调用了不存在的 API 方法等,即使您调用getDeclaredMethods
; 仅当实际运行有问题的代码行时,VM 才会报告错误。
BCEL 5.2 中的 JustIce 似乎是最简单的;
org.apache.bcel.verifier.Verifier.main(new String[] {clazz});
做这项工作:
Pass 3a, method number 1 ['public void m()']:
VERIFIED_REJECTED
Instruction invokestatic[184](3) 4 constraint violated:
Referenced method 'x' with expected signature '()V' not found in class 'API'.
....
我尝试了 ASM 4.0,但是
org.objectweb.asm.util.CheckClassAdapter.main(new String[] {clazz});
不工作;也许它检查方法的格式,但不检查链接。内联main
和传递checkDataFlow=true
没有帮助。
搜索,我还找到了https://kenai.com/hg/maxine~maxine/file/8429d3ebc036/com.oracle.max.vm/test/test/com/sun/max/vm/verifier/CommandLineVerifier.java但我找不到任何方法来完成这项工作;随附的单元测试在运行时会抛出一个ClassNotFoundException
。