java - 通过 ASM 在字节码中添加 try/catch block 时出现VerifyError

标签 java java-bytecode-asm

在我的 Java 代理中,我使用 ASM 来检测类。我试图用 try/catch 包装特定的方法,加上跟踪 methodEntermethodExit

使用“-noverify”,代码可以完美运行。

如果没有此选项,它会失败并显示 VerifyError(“此位置的预期堆栈映射帧”)——显然是因为我没有调用访问帧。

我将 COMPUTE_MAXS 用于 ClassWriter,将 EXPAND_FRAMES 用于 ClassReader。我无法使用 COMPUTE_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() 调用。

此外,不必加载依赖类。您可以提供您自己的 ClassWriter.getCommonSuperClass() 的实现。例如,参见ClassWriterComputeFramesTest .

关于java - 通过 ASM 在字节码中添加 try/catch block 时出现VerifyError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38661035/

相关文章:

java - 哪个 Java 访问修饰符允许成员只能由其他包中的子类访问?

java - 有没有办法知道访问字节码时使用 `new` 创建了哪些类?

java - 计算方法的字节码大小

java - try/catch/finally block 中的执行顺序与 try block 中的复合返回语句

java - 如何将maven版本设置为Javadoc中的@version标签?

java - IDE 想要将我的 Int 转换为 boolean 值?我的方法之一说它不能应用

java - 如何使用 ASM 控制常量池条目的顺序?

java - 无法从空堆栈中弹出操作数

java - JVM 类加载中的意外行为(真正需要类之前的 ClassNotFoundException)

java - 如何在android中使用文件发送参数