Java ASM AdviceAdapter没有检测所有方法

时间:2015-10-06 16:42:42

标签: java bytecode instrumentation java-bytecode-asm

我试图通过从AdviceAdapter实现onMethodEnter()来捕获每个方法调用的调用。我遇到的问题是,我的检测代码没有被添加到所有方法中。实际上,它仅添加到“<init>”之后的第一个方法中,并且跳过了其余的方法。请在下面的代码中告诉我我做错了什么。

感谢。 灰分。

public class FunctionLevelDependency extends AdviceAdapter implements Opcodes {
    String className;
    String methodName;
    int currentThread_idx, threadId_idx, stringBuffer_idx, output_idx;

    protected FunctionLevelDependency(int api, MethodVisitor mv, int access,
            String methodName, String desc, String className) {
        super(api, mv, access, methodName, desc);
        this.className = className;
        this.methodName = methodName;
    }

    @Override
    protected void onMethodEnter() {
        currentThread_idx = newLocal(Type.getType(Thread.class));
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "currentThread",
                "()Ljava/lang/Thread;", false);
        mv.visitVarInsn(ASTORE, currentThread_idx);
        mv.visitVarInsn(ALOAD, currentThread_idx);
        threadId_idx = newLocal(Type.getType(String.class));
        mv.visitTypeInsn(NEW, "java/lang/String");
        mv.visitInsn(DUP);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>",
                "()V", false);
        mv.visitVarInsn(ASTORE, threadId_idx);
        mv.visitVarInsn(ALOAD, currentThread_idx);

        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Thread", "getName", "()Ljava/lang/String;",
                false);
        mv.visitVarInsn(ASTORE, threadId_idx);

        stringBuffer_idx = newLocal(Type.getType(StringBuffer.class));
        mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
        mv.visitInsn(DUP);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>",
                "()V", false);
        mv.visitVarInsn(ASTORE, stringBuffer_idx);
        mv.visitVarInsn(ALOAD, stringBuffer_idx);
        mv.visitVarInsn(ALOAD, threadId_idx);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append",
                "(Ljava/lang/String;)Ljava/lang/StringBuffer;", false);
        mv.visitInsn(POP);
        mv.visitVarInsn(ALOAD, stringBuffer_idx);
        mv.visitLdcInsn(",[" + className + "][" + methodName + "]");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append",
                "(Ljava/lang/String;)Ljava/lang/StringBuffer;", false);
        mv.visitInsn(POP);
        mv.visitVarInsn(ALOAD, stringBuffer_idx);

        output_idx = newLocal(Type.getType(String.class));
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString",
                "()Ljava/lang/String;", false);
        mv.visitVarInsn(ASTORE, output_idx);
        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                "Ljava/io/PrintStream;");
        mv.visitVarInsn(ALOAD, output_idx);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                "(Ljava/lang/String;)V", false);

    }

}

public class FunctionDependencyPrinter extends ClassVisitor {
    private String className;
    private boolean isInterface;

    public FunctionDependencyPrinter(ClassWriter writer, String className) {
        super(Opcodes.ASM5, writer);
        this.className = className;
    }

    @Override
    public void visit(int version, int access, String name, String signature,
            String superName, String[] interfaces) {
        super.visit(version, access, name, signature, superName, interfaces);
        isInterface = (access & ACC_INTERFACE) != 0;
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String desc,
            String signature, String[] exceptions) {
        MethodVisitor mv = super.visitMethod(access, name, desc, signature,
                exceptions);
        if (!isInterface && mv != null && !name.equals("<init>") && !name.equals("<clinit>")) {
            System.out.println("Transforming " + name + " for " + className);
            mv = new FunctionLevelDependency(Opcodes.ASM5, mv, access, name,
                    desc, className);
        }
        return mv;
    }
}

0 个答案:

没有答案