2017-03-20 11 views
0

私は最初のJavaエージェントを作成しています。私はgit repo(私によって開発されたものではない)から選んだプロジェクトを計測しようとしています。Javaエージェント - 選択したファイルを計測する(組み込みのJavaクラスとメソッドをすべて除外)

私は、私も作り付けのJava機能は、/クラスがある呼び出すことがわかり、しかし(ASMバイトコード操作フレームワークを使用して実行された行の数を記録します)

をpremainメソッドで私のエージェントクラスを書かれており、いくつかのログを実装していますインストゥルメントが不正確です。プロジェクト内のファイルを計測するだけです。私はこのフィルタを追加した後

public static void premain(String agentArgs, Instrumentation inst) { 

    System.out.println("Premain called"); 

    inst.addTransformer(new ClassFileTransformer() { 
     public byte[] transform(ClassLoader classLoader, 
           String className, 
           Class<?> classBeingRedefined, 
           ProtectionDomain protectionDomain, 
           byte[] bytes)throws IllegalClassFormatException { 


     // ASM Code 
     if(className.startsWith("org/mytestpackage/")){ 
      ClassReader reader = new ClassReader(bytes); 
      ClassWriter writer = new ClassWriter(reader, 0); 
      ClassTransformVisitor visitor = new ClassTransformVisitor(writer); 
      reader.accept(visitor, 0); 
      return writer.toByteArray(); 
     } 

     return null; 

     } 
    }); 

    } 

状態ならば、premainが呼び出されているが、私はこのフィルタを追加する前に、私は(一部の例外

initializationError(org.mytestpackage.TestAllPackages) Time elapsed: 0.002 sec <<< ERROR! 
java.lang.VerifyError: (class: org/mytestpackage/TestAllPackages, method: main signature: ([Ljava/lang/String;)V) Stack size too large 
     at java.lang.Class.getDeclaredMethods0(Native Method) 
     at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) 
     at java.lang.Class.privateGetMethodRecursive(Class.java:3048) 
     at java.lang.Class.getMethod0(Class.java:3018) 
     at java.lang.Class.getMethod(Class.java:1784) 

を取得しています - これを実現するために、私は、以下に示すフィルタを追加しましたclassNameに基づいて)、私は自分のロジックがinbuilt javaクラスとメソッドのために働くのを見ることができました。フィルタを追加した後に失敗した場合。

TIAを助けてください。

答えて

1

ClassTransformVisitorは、あなたの変換されたケースのコードを壊しているようです。あなたの特別なケースでは、あなたのクラスのメソッドのスタックサイズを調整していないようですorg.mytestpackage.TestAllPackages

ベリファイアエラーStack size too largeは、このスタックのスロットとして指定した値より多くの値をメソッドのオペランドスタックにプッシュすることを示します。 new ClassWriter(reader, ClassWriter.COMPUTE_MAXS)を指定すると、ASMにこの問題を解決するように依頼できます。

+0

はい、問題でした。彼らは私がクラスライターを作った方法で問題を引き起こしているようでした。ありがとうございました。 – maddie

+0

自分で最大サイズを計算していない場合は、スタックマップフレームを作成していないと思います。だからクラスのバージョンが50以上の場合、両方を計算するのに 'ClassWriter.COMPUTE_FRAMES'を使うべきです。 – Holger

関連する問題