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

Getting VerifyError when adding try/catch block in bytecode through ASM

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

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

如果没有此选项,它会失败并显示 VerifyError ("Expected stackmap frame at this location")——显然是因为我没有调用 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();
    }
}

// ...

非常欢迎任何帮助。

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

此外,依赖 类 不必加载。您可以提供自己的 ClassWriter.getCommonSuperClass(). For example, see ClassWriterComputeFramesTest.

实现