提问者:小点点

如何在使用asm库进行插桩的方法中找到空的局部变量


在为一个类的不同方法进行插桩时为了使一个方法在文本文件中做写操作。我首先将字符串存储在一个显式定义的局部变量3160中。如何选择这些变量以防止与已经存在的变量发生冲突。

就像在这个片段中,代码每次进入任何方法时都会将类名写入文本文件。为了做到这一点,必须使用变量3160将字符串s加载到堆栈上(值保持较大,以便已经定义的变量名不会与变量s(3160)冲突)。我的问题是如何在使用ASM库进行插桩时在方法中定义局部变量。这个问题对许多人来说似乎有点为时过早,但那是因为我是初学者。

    String s= className;
    mv.visitLdcInsn(s);
    mv.visitVarInsn(Opcodes.ASTORE, 3160);
    mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder");
    mv.visitInsn(Opcodes.DUP);
    mv.visitVarInsn(Opcodes.ALOAD, 3160);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;");
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/me/database/dataCollectionFile/Info", "callMeAnyTime", "()Ljava/lang/String;");
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");

共3个答案

匿名用户

您应该使用LocalVariablesSorter适配器(从它扩展您自己的访问者,或者将其添加到方法作家之前的访问者链)。然后,当您需要一个新变量时,您可以调用LocalVariablesSorter. newLocal()方法来分配新的变量槽。有关更多详细信息,另请参阅ASM指南。

匿名用户

我会查看局部变量调试表,我会使用下一个可用的id,它更有可能是2或10,而不是3160。

如果没有调试信息,可能需要多扫码一次,先看看用了多少id。

注意:由于历史原因,doublelong需要两个id。

匿名用户

newLocal(Type. type)是我发现的会对我的情况有所帮助,谢谢尤金·库勒绍夫和

彼得·劳里的帮助:)

相关问题