我的目标是在一些 Java 字节码的每个基本块的开头插入少量代码。目的是通过基本块记录执行路径。目前,我正在使用 Javassist 在方法的开头和结尾检测一些代码,但我在检测更精细的字节码位置时遇到了 Javassist API 的困境。
Javassist 为我提供了一个 Block[],它表示方法中的所有基本块。基本块可以报告它们的字节码位置,所以我知道我的仪器需要去哪里。我想使用的 Javassist 工具是 CtMethod.insertAt(int sourceCodeLineNumber,String newSourceCode),但是它使用源代码行号而不是字节码行号,这导致了这个问题中说明的问题(我相当确定没有至此解决该问题)。
问题:当变量本身来自 Javassist instrumentation 时,如何使用 Instrumentation 为方法中的变量赋值。我最好不必使用其他工具,但我正在寻求我能得到的任何帮助。
使用 Javassist 像这样声明变量:
//m is a CtMethod
try { m.addLocalVariable("someVar", ClassPool.getDefault().get("SomePackage.SomeClass")); }
catch (NotFoundException e) { e.printStackTrace(); }
我最坏的情况是以某种方式推断 javassist 工具的堆栈变量并使用遍历整个方法/类的迭代器插入字节码,但这真的很讨厌。我的方法只有一个整数输入(块 ID)和 void 输出,所以 Java 字节码在每个基本块的开头看起来像这样:
ALOAD 6 //6 is my new Javassist variable ID, however I don't think I can get Javassist to actually tell it to me
ICONST_1 //My parameters, which is an int. I'd have to switch statement between ICONST, SIPUSH, and ALOAD depending on basic block's index size
INVOKEVIRTUAL SomePackage/SomeClass.SomeMethod(I)V