1

ネイティブ メソッドが特定の Linux syscall を (直接的または間接的に) 呼び出したときにトリガーされるブレークポイントを Java に設定するにはどうすればよいですか?

4

2 に答える 2

1

これは完全なブレークポイントではありませんが、少なくともスタック トレースが得られるので、これで十分かもしれません。さらに、必要に応じて、Systemtap 言語を使用すると、スタック トレースを出力するだけでなく、さらに多くのことを実行できます。

IcedTea JVM ソース コードには、実行中の IcedTea (Hotspot を使用) JVM からスタック トレースを取得するために使用できる関数を含むSystemTap ファイルがあります。私が理解しているように、これらの関数を使用すると、SystemTap がサポートするすべてのイベントから Java スタック トレースを取得できます。カーネル内のイベントからでも取得できます。

これらの jstack 関数は、名前は同じですが、JDK で提供される jstack(1) コマンドライン ユーティリティとは無関係であることに注意してください。これらは、JVM へのコールバックではなくメモリ インスペクションを介して動作するため、Hotspot 内部に非常に固有のものであり、非 Hotspot ベースの JVM では動作しない可能性があります。

注: Systemtap はデフォルトの Debian カーネルでは完全には機能しないため、Debian ベースのシステムでは独自のカーネルをコンパイルする必要がある場合があります。この問題は、Fedora または Red Hat には影響しません。

于 2012-07-21T08:55:26.853 に答える
0

理論的には、Java 用の事前 (AOT) コンパイラを使用してアプリケーションをネイティブ コンパイルし、ネイティブ デバッガを使用してシステムコールにブレークポイントまたはキャッチポイントを設定することが可能です。(おまけ: ネイティブ メソッドによって呼び出されたすべての C 関数を含む完全なスタック トレースと、それらの C 関数をシームレスにデバッグする機能が得られます。)

おそらく、AOT コンパイラーによって生成された名前をデマングルする方法を知っているデバッガーを使用したいと思うでしょう。たとえば、gdb は gcj によって生成された名前をデマングルする方法を知っているため、gcj と gdb の組み合わせが機能するはずです。

この組み合わせの問題点は、gcj がまだ JDK 1.5 の部分的な互換性にとどまっていることと、誰も OpenJDK クラス ライブラリでマージする作業を行っていないことです (2009 年に gcj メーリング リストで提案されました)。その結果、gcj は決して一般的なオプションではありませんでした。意図せずに (特に Debian と Ubuntu で) 使用することがよくありますが、問題が発生すると、バグを報告する代わりに、より標準的な JDK に切り替える傾向があります。

また、AOT コンパイラを使用したネイティブ コンパイルは、必要に応じて JRE がコードを JIT コンパイルするよりもはるかに遅くなります。

于 2012-07-21T08:20:01.457 に答える