【发布时间】:2014-07-22 08:06:21
【问题描述】:
我正在尝试使用 ASM 注入字节码,我想用 try-catch 块包围注入的字节码。但是,我在 onMethodExit 上得到了一个 VerifyError:“不一致的堆栈高度 0 != 1”。
删除 try-catch 块后,它会按预期工作。任何指针都非常感谢。
这是我的代码快照:-----
protected void onMethodEnter() {
mv.visitInsn(Opcodes.ICONST_0);
mv.visitVarInsn(ISTORE, okFlag);
Label startTryBlock = new Label();
Label endTryBlock = new Label();
Label startCatchBlock = new Label();
// Initialization try-catch block
mv.visitTryCatchBlock(startTryBlock, endTryBlock, startCatchBlock, "java/lang/Exception");
// starting try block
mv.visitLabel(startTryBlock);
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitLdcInsn(description);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/sam/agent/trace/RootTracer", "allMethodBegin", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
mv.visitVarInsn(ISTORE, okFlag);
//ending try block
mv.visitLabel(endTryBlock);
Label endCatchBlock = new Label();
mv.visitJumpInsn(GOTO, endCatchBlock);
// start catch block
mv.visitLabel(startCatchBlock);
mv.visitVarInsn(ASTORE, isStatic);
//ending catch block
mv.visitLabel(endCatchBlock);
}
private void onMethodExit(int opcode) {
Label startTryBlock = new Label();
Label endTryBlock = new Label();
Label startCatchBlock = new Label();
// Initialization try-catch block
mv.visitTryCatchBlock(startTryBlock, endTryBlock, startCatchBlock, "java/lang/Exception");
// starting try block
mv.visitLabel(startTryBlock);
if(opcode == ATHROW){
mv.visitInsn(Opcodes.DUP);
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitLdcInsn(description);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/sam/agent/trace/RootTracer", "recordException", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
}
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitLdcInsn(description);
mv.visitVarInsn(ILOAD, okFlag);
mv.visitLdcInsn(opcode);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/sam/agent/trace/RootTracer", "MethodEnd", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZI)V");
// ending try block
mv.visitLabel(endTryBlock);
Label endCatchBlock = new Label();
mv.visitJumpInsn(GOTO, endCatchBlock);
// starting catch block
mv.visitLabel(startCatchBlock);
mv.visitVarInsn(ASTORE, isStatic); // FAILED Here
// ending catch block
mv.visitLabel(endCatchBlock);
}
【问题讨论】: