我正在编写一个小工具来使用ASM 5执行字节码的静态分析。我将我的输入Java类提供给ClassReader,它触发自定义ClassVisitor的事件。如果符合某些条件,我的ClassVisitor会覆盖visitMethod
以返回我的自定义MethodVisitor,如果不符合,则会覆盖null
。
问题是,ClassReader从不调用MethodVisitor的方法;我使用NetBeans调试它,我看到访问者被正确返回(它不是null
)但仍然执行永远不会进入visitMethodInsn
,即使是方法指令我正在用于测试的课程。
之前我使用过ASM,但这是我第一次遇到这个问题。
以下是MyClassVisitor.visitMethod
的代码:
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
InvokeFinder visitor;
if(condition.isMet()) {
visitor = new InvokeFinder(api);
visitor.doStuff();
} else {
visitor = null;
}
return visitor;
}
这里是InvokeFinder
的代码,在执行期间从不输入:
public class InvokeFinder extends MethodVisitor {
public InvokeFinder(int api) {
super(api);
}
void unrelatedMethod(String parameter) {
doStuff(parameter);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
switch (opcode) {
case Opcodes.INVOKEVIRTUAL:
case Opcodes.INVOKESPECIAL:
case Opcodes.INVOKEDYNAMIC:
doSomething();
break;
case Opcodes.INVOKEINTERFACE:
doSomethingElse();
break;
case Opcodes.INVOKESTATIC:
doSomethingDifferentAgain();
break;
default: break;
}
}
}
最后这是我正在测试的类(这不是要执行的,它的唯一目的是编译然后通过我的工具进行分析):
public class MyTestClass{
public MyTestClass(String s) {
System.out.println( "Function Name" );
}
public static void main(String args[]) {
CGraph g = new CGraph("entry");
g.enterBF(new CGVisitor() {
@Override
public void nodeOperations(CGraph graph, CGraphNode currentNode) {
System.out.println("20");
}
@Override
public String getString() {
throw new UnsupportedOperationException("No string can be returned from this anonymous implementation of CGVisitor.");
}
});
a( 11 );
}
public static void a(int n) {
b( n );
}
public static void b(int m) {
int n;
if (m >= 10)
a( m-1 );
else
System.out.println(m);
}
}
我仔细检查了上面的visitMethod
方法总是被执行,返回一个非空的InvokeFinder
实例,并且这个实例永远不会被执行;如果在InvokeFinder.visitMethodInsn
的某些方法中存在调用指令(例如,在方法MyTestClass
内),那么在这些条件下a(int)
怎么可能永远不会被ClassReader调用?
编辑:进一步调试,我发现ClassReader调用默认的MethodVisitor.visitMethodInsn
而不是调用被覆盖的版本InvokeFinder.visitMethodInsn
。为什么会这样?
答案 0 :(得分:0)
原来我改变了ASM的API版本,版本4和5之间MethodVisitor.visitMethodInsn
的签名不同。动态绑定不再将其视为最重要的方法。
我可以通过将缺少的参数添加到InvokeFinder.visitMethodInsn
来解决这个问题,public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf)
的签名现在是
Ext.Ajax.request({
method: 'POST',
url: g_globalsFromJsp.contextPath + '/UploadAction0.do',
params: formData,
success: function (response, opts) {
if (response.status ===200) { // OK
//Error Here
document.open();
document.write(response.responseText);
document.close();
}
},
failure : function(response, opts) {
//SomeAlertMessage
}
})