Java 通过ASM在字节码中添加try/catch块时获取VerifyError
在我的Java代理中,我使用ASM检测类。我试图用try/catch包装特定的方法,并跟踪Java 通过ASM在字节码中添加try/catch块时获取VerifyError,java,java-bytecode-asm,Java,Java Bytecode Asm,在我的Java代理中,我使用ASM检测类。我试图用try/catch包装特定的方法,并跟踪methodEnter和methodExit 使用“-noverify”代码可以完美地工作 如果没有此选项,它将失败并出现VerifyError(“此位置的预期堆栈映射帧”)——显然是因为我没有调用visitFrame 我对ClassWriter使用COMPUTE\u MAXS,对ClassReader使用EXPAND\u FRAMES。我不能使用COMPUTE\u FRAMES,因为它将要求在插装之前加载
methodEnter
和methodExit
使用“-noverify”
代码可以完美地工作
如果没有此选项,它将失败并出现VerifyError
(“此位置的预期堆栈映射帧”)——显然是因为我没有调用visitFrame
我对ClassWriter
使用COMPUTE\u MAXS
,对ClassReader
使用EXPAND\u FRAMES
。我不能使用COMPUTE\u FRAMES
,因为它将要求在插装之前加载所有依赖类,这是不可能的
我当前的代码:
// ...
@Override
protected void onMethodEnter() {
visitLogMethodCallEntry();
}
@Override
public void visitCode() {
super.visitCode();
mv.visitLabel(startFinally);
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
Label handler = new Label();
mv.visitTryCatchBlock(startFinally, handler, handler, null);
mv.visitLabel(handler);
visitLogMethodCallException();
mv.visitInsn(ATHROW);
mv.visitMaxs(maxStack, maxLocals);
}
@Override
protected void onMethodExit(int opcode) {
if (opcode != ATHROW) {
visitLogMethodCallExit();
}
}
// ...
非常欢迎提供任何帮助。乍一看,在没有看到导致问题的完整代码的情况下,您混淆了super.visitXX()和mv.visitXX()调用
此外,不必加载依赖类。您可以提供自己的实现。例如,请参阅。关于super.visitXX()和mv.visitXX()调用,您是对的,但这不是问题的原因。至于“不必加载依赖类”,我根本不确定您是否就在这里。如果使用COMPUTE_MAXS,则需要ClassWriter.getCommonSuperClass()的正确实现。我看过ClassWriterComputeFramesTest,但找不到任何有用的代码。你是什么意思?其中有一个被覆盖的getCommonSuperClass()。检查它,但您可能必须编写自己的类存储库抽象来内省对象层次结构而不进行反射。至于其他问题,您必须在一个简单的单元测试中隔离它。您发布的代码段不完整。Eugene,如果您查看ClassWriterComputeFramesTest,您将看到它引用getCommonSuperClass()中的classLoader来获取类的实例。这在Java代理中不起作用,因为类加载器尚未加载这些类。它使用ClassLoader加载资源并处理这些资源以获取类型信息,但不加载类。