メソッドの入口/出口のための ASM バイトコード計測
-
13-09-2019 - |
質問
次のことを高レベルで実行する JVMTI エージェントを作成しました。
onClassLoadHook は、ロードされたクラスのバイトコードを、ASM を使用してクラスを計測する別の Java プロセスに送信します。
バイトコードを取得してロードします
ロードされた Java クラスを計測する別の Java プロセスでは、次のことを行います。
.. ..
cr = new ClassReader(inBytes, offset, inLen);
cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ClassAdapter ca = new ClassAdapter(cw) {
..
..
@Override
public MethodVisitor visitMethod(final int access,
final String name,
final String desc,
String signature,
String[] exceptions) {
return new MethodAdapter(mv) {
@Override
public void visitCode() {
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/amir/Tester", "callTestStatic3", "(Ljava/lang/Object;)V");
mv.visitCode();
}
}
}
Java Decompiler を使用して、このインストルメンテーションの後に記述されたクラスを逆コンパイルしようとすると、次の逆コンパイルされた関数が表示されますが、これは間違っていることがわかります。
public void func1(int arg1, int arg2)
{
int b;
Tester.callTestStatic3(???);
System.out.println("arg = " + a + " b = " + b);
}
私の関数は実際には次のように見えるからです:
public void func1(int a, int b)
{
System.out.println("arg = " +a + " b = " +b);
}
ここで私が何か間違ったことをした場合、誰か教えてもらえますか?私の唯一の手がかりは、関数の引数として THIS ポインターを渡す代わりに、プリミティブ型を渡せば、すべてがうまくいくということです。THIS ポインタについて、管理する必要がある特別な点はありますか?バイトコードを比較し、ASMIFIER を使用して、正しいバイトコードを生成するにはどのステートメントを使用する必要があるのかを知ることができました。
解決
mv.visitCode() を使用したコードは正しいようです。javap は予期されるバイトコードを示します。元の逆コンパイラが正しい動作をしていなかったのだろうと思います。
他のヒント
関係ないかもしれないけど、電話したほうがいいんじゃないでしょうか super.visitCode()
?
@Override
public void visitCode() {
super.visitCode();
...
私なら使います トレースクラスビジター 何が生成されているかを正確に確認します。
所属していません StackOverflow