Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过ASM在字节码中添加try/catch块时获取VerifyError_Java_Java Bytecode Asm - Fatal编程技术网

Java 通过ASM在字节码中添加try/catch块时获取VerifyError

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,因为它将要求在插装之前加载

在我的Java代理中,我使用ASM检测类。我试图用try/catch包装特定的方法,并跟踪
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加载资源并处理这些资源以获取类型信息,但不加载类。