通过 ASM 在字节码中添加 try/catch 块时出现 VerifyError
Getting VerifyError when adding try/catch block in bytecode through ASM
在我的 Java 代理中,我正在使用 ASM 检测 类。我试图用 try/catch 包装特定方法,加上跟踪 methodEnter
和 methodExit
.
使用 "-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.
实现
在我的 Java 代理中,我正在使用 ASM 检测 类。我试图用 try/catch 包装特定方法,加上跟踪 methodEnter
和 methodExit
.
使用 "-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.
实现