【问题标题】:Getting VerifyError when adding try/catch block in bytecode through ASM通过 ASM 在字节码中添加 try/catch 块时出现 VerifyError
【发布时间】:2016-07-29 14:13:40
【问题描述】:

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

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

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

我将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();
    }
}

// ...

非常欢迎任何帮助。

【问题讨论】:

    标签: java java-bytecode-asm


    【解决方案1】:

    乍一看并没有看到导致问题的完整代码,您正在混淆 super.visitXX() 和 mv.visitXX() 调用。

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

    【讨论】:

    • 关于 super.visitXX() 和 mv.visitXX() 调用是对的,但这不是问题的原因。至于“不必加载依赖类”,我完全不确定您是否在这里。如果使用 COMPUTE_MAXS,则需要正确实现 ClassWriter.getCommonSuperClass()。我看过 ClassWriterComputeFramesTest 并找不到任何有用的代码。
    • 什么意思?那里有一个被覆盖的 getCommonSuperClass() 。检查它,但您可能必须编写自己的类存储库抽象来内省对象层次结构而无需反射。
    • 至于其他问题,您必须在一个简单的单元测试中将其隔离。您发布的 sn-p 不完整。
    • Eugene,如果你看一下 ClassWriterComputeFramesTest,你会发现它引用了 getCommonSuperClass() 中的 classLoader 来获取类的实例。这在 Java 代理中不起作用,因为 classLoader 尚未加载类。
    • 仔细看看。它使用 ClassLoader 加载资源并处理这些资源以获取类型信息,但它不加载类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    相关资源
    最近更新 更多