私のバイトコードインストルメンテーションプロジェクトでは、VerifyErrorsに頻繁に遭遇します。ただし、デフォルトのjava Verifierは、どの命令がエラーを引き起こしたかについての情報をほとんど提供しません(メソッドと小さなメッセージのみを提供します)。エラーの特定、少なくとも正確な命令位置の特定にもう少し高度なヘルプを提供するスタンドアロンのバイトコードベリファイアはありますか?ありがとうございました。
3 に答える
また、潜在的な検証エラーを報告するものも探していましたが、特にIncompatibleClassChangeError
s. 1 つの API クラスと、API メソッドを呼び出す別のクライアント クラス、およびベリファイアを実行するためのメイン クラスを含む小さなテスト プロジェクトを作成しました。次に、API を変更し、クライアントではなく API を再コンパイルし、何がキャッチされるかを確認しました。-target 7
今のところ特別な JDK 7 機能はありませんが使用されます。
まず、最も明白Class.forName
なことですが、クライアント クラスのシグネチャで特定のエラーを見つけることができますが、メソッド本体で、存在しない API メソッドなどへの呼び出しをチェックしていないようですgetDeclaredMethods
。問題のあるコード行が実際に実行された場合にのみ、VM によってエラーが報告されます。
BCEL 5.2 の JustIce が最も簡単なようです。
org.apache.bcel.verifier.Verifier.main(new String[] {clazz});
仕事をします:
Pass 3a, method number 1 ['public void m()']:
VERIFIED_REJECTED
Instruction invokestatic[184](3) 4 constraint violated:
Referenced method 'x' with expected signature '()V' not found in class 'API'.
....
ASM4.0を試してみましたが、
org.objectweb.asm.util.CheckClassAdapter.main(new String[] {clazz});
動作しません; おそらく、メソッドの形式はチェックしますが、リンケージはチェックしません。インラインmain
化とパスcheckDataFlow=true
は役に立ちません。
検索すると、https://kenai.com/hg/maxine~maxine/file/8429d3ebc036/com.oracle.max.vm/test/test/com/sun/max/vm/verifier/CommandLineVerifier.javaも見つかりましたが、これを機能させる方法が見つかりませんでした。付随する単体テストはClassNotFoundException
実行時にスローします。
ASM CheckClassAdaptor.verify() は素晴らしいフィードバックを提供します: http://asm.ow2.org/