2016-10-31 12 views
1

JVMI関数RetransformClassesとイベントフックClassLoadFileHookを使用してクラスを計測しようとするやや複雑なアーキテクチャがありますが、JNIを使​​用して変換を実行するにはJava空間に移動します。 ClassLoadFileHookでは、インストルメントしたいクラスに対してそれが実行されているかどうかを確認し、そうであれば、ASM 5.0.4を使用して計測を実行するJavaクラスにJNI呼び出しを行います。つまり、Javaの領域では、インストルメントされたクラスを表すバイト配列を取得してから、ネイティブコードを呼び出して更新を適用します。ASMバイトコード置換機能が完了していません

私が経験しています問題は、私はインスタンス化した後、私はクラスを再変換私のJavaコードで、コードは/中にハングしているということですClassReader

/** 
* Transform some class and then call back down to native code to apply 
* the transformation. 
* 
* @param existingClass The existing class to change. 
*/ 
public synchronized void transformSomeClass(byte[] existingClass) { 
    System.out.println("Transformation function started. Existing class len: " + existingClass.length); 
    try { 
     ClassReader cr = new ClassReader(existingClass); 
     // No statements below here are being executed. 
     // I'm also not sure if `new ClassReader` is being successfully 
     // executed. 
     System.out.println("After ClassReader instantiation"); 
     ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 
     System.out.println("After ClassWriter instantiation"); 
     ClassVisitor cv = 
       new MyCustomClassAdapter(cw, this.lineNumberToPlaceUpdate_); 
     System.out.println("After ClassVisitor instantiation"); 
     cr.accept(cv, 0); 
     System.out.println("After cv accept."); 

     System.out.println("Applying class transformation natively."); 
     // Call back down to native code to apply the update in ClassLoadFileHook. 
     applyClassTransformNative(cw.toByteArray()); 
     System.out.println("Transformation function ended."); 
    } catch (Exception e) { 
     // This is never being fired. 
     System.err.println("Class transformation could not be completed. Error message: " + e.getMessage()); 
     e.printStackTrace(); 
    } finally { 
     // This print statement is never executed. 
     System.err.println("Going back to native code from finally"); 
    } 
} 

私はコードのコメントで言及したよう、intentiation文が実行された後は何もありません。 finallyブロックさえ実行されません。私はここで何が起きているのかよく分かりません。なぜClassReaderが一般的なバイト配列を取ってインスタンス化すると、コードがこのようにハングアップするのですか?私は実際にそのクラスで何の操作も行っていない。

+0

「new ClassReader」が戻ってこないかどうかわからない理由を知りたい人のための副作用として/私がデバッガを使用していない理由 - 私が作っているJNI呼び出しは、私が知る限り、デバッガを使用する贅沢はなく、Javaプロセスは単一のエージェントしか実行できません。私が間違っていると、なぜ誰かが理由を説明し、デバッガの使い方を教えてくれていることに感謝します。 – DIMMSum

+3

ASMクラスをロードしているクラス・ローダーを暗黙的にロックするクラス・ロードをトリガーしているとします。したがって、あなたのコードは進展しません。それ以外の場合、あなたはあなたの出力を得るでしょう。 –

+0

"Javaプロセスは単一のエージェントしか実行できません"?私はそのような制限について聞いたことがありません。私は確かにそれをテストし、複数のエージェントを実行しても問題はありませんでした... – Holger

答えて

3

Javaコードの呼び出しによってクラスが読み込まれる場合は、クラスをロードするクラスローダーを暗黙的に同期させます。私はあなたがネイティブレイヤーでそのようなクラスローディングをトリガーし、Javaレイヤー上で再度トリガーしようとするとブロックされると仮定します。このため、Javaでクラスを変換しようとすると、最初のASMクラスを超えて進化することはありません。

関連する問題