Javaエージェントでは、ASMを使用してクラスを実装しています。私はtry/catchで特定のメソッドをラップしようとしており、トレースはmethodEnter
とmethodExit
です。ASMを使用してバイトコードにtry/catchブロックを追加するとVerifyErrorが発生する
"-noverify"
のコードは完全に機能します。
このオプションを指定しないとVerifyError
( "この場所のスタックマップフレームが予想されます")で失敗します - 私はvisitFrameを呼び出さないためです。
COMPUTE_MAXS
をClassWriter
に、EXPAND_FRAMES
をClassReader
に使用しています。 COMPUTE_FRAMES
を使用することはできません。これは、すべての依存クラスを計測前にロードする必要があります。これは不可能です。
私の現在のコード:
// ...
@Override
protected void onMethodEnter() {
visitLogMethodCallEntry();
}
@Override
public void visitCode() {
super.visitCode();
mv.visitLabel(startFinally);
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
Label handler = new Label();
mv.visitTryCatchBlock(startFinally, handler, handler, null);
mv.visitLabel(handler);
visitLogMethodCallException();
mv.visitInsn(ATHROW);
mv.visitMaxs(maxStack, maxLocals);
}
@Override
protected void onMethodExit(int opcode) {
if (opcode != ATHROW) {
visitLogMethodCallExit();
}
}
// ...
すべてのヘルプは大歓迎です。
あなたはsuper.visitXX()とmv.visitXX()呼び出しについて正しいですが、それは問題の原因ではありません。 「依存クラスを読み込む必要はありません」に関しては、あなたがここにいることは全くわかりません。 COMPUTE_MAXSを使用する場合は、ClassWriter.getCommonSuperClass()の適切な実装が必要です。私はClassWriterComputeFramesTestを見たことがあり、有益なコードが見つかりませんでした。 –
どういう意味ですか?そこに上書きされたgetCommonSuperClass()があります。これを確認しますが、独自のクラス・リポジトリ抽象化を作成して、リフレクションなしでオブジェクト階層をイントロスペクションする必要があります。 –
その他の問題については、単純な単体テストで分離する必要があります。投稿したスニペットは完全ではありません。 –