デバッグ・エージェントなしで利用できない場合NullPointerExceptionスタックトレース
-
21-08-2019 - |
質問
私は最近、NullPointerExceptionが発生するバグを発見しました。例外がキャッチされ、標準SLF4J文を使用して記録されます。下記の要約版のコード:
for(Action action : actions.getActions()) {
try {
context = action.execute(context);
} catch (Exception e) {
logger.error("...", e);
break;
}
}
あなたが見ることができるように、何も空想。しかし、我々が持っているすべての例外のロギング文で、この1つだけでは、スタックトレースを出力しません。それは印刷し、すべてのメッセージ(「...」と表される)と例外クラス(java.lang.NullPointerExceptionが)の名前です。
例外のスタックトレースが遅延ロードされているので、、私は多分、ある種の命令の並べ替え問題があると思ったし、ログ文の前e.getStackTrace()を呼び出すことにしました。これは何の違いを行っていない。
だから私は、デバッグ・エージェントを有効にして再起動することを決めました。私もプロセスに添付しかし、私は今、スタックトレースが印刷されたことに気づきました。だから、はっきりとデバッグ剤の存在は、いくつかの追加のデバッグ情報が利用可能になった原因ます。
私は、例外の根本的な原因を固定するので持っています。しかし、私は、スタックトレースは、デバッガなしで利用できなかった理由を知りたいです。誰もが知っている?
明確化:これは伐採問題のではありません。同じのtry / catch句を想像しますが、キャッチで、私はの値を印刷します:
e.getStackTrace().length
デバッガせずにこの印刷「0」、それは正の数(ここでは9)を印刷するデバッガと
詳細情報:これはJDK 1.6.0_13上で起こっている、64ビット、AMD64、Linuxの2.6.9
解決
それは、このコードは内部ループであることは可能ですか?そして、その後、JITコンパイラは、スタック情報を失う、ネイティブコードに、このためにコールスタックをコンパイルすることがあります。あなたがデバッガをアタッチするとき、それは、再び情報を利用可能にする、JITを無効にします。
他の手動の例外はJITが最適化されていないような情報を表示し続ける。
これは時々ライン102で、このクラスのソースコード内のコメントから、他人のために発生する可能性がありますように見えます:
ます。http://logging.apache。 ORG / log4jの/ 1.2 / XREF /組織/ apacheの/ log4jの/ SPI / LocationInfo.htmlする
他のヒント
JVMフラグ-XX付:あなたはこのユースケースのためにJVMのパフォーマンスの最適化を無効にすることができ-OmitStackTraceInFastThrow。このパラメータが指定された場合、フラグを無効にする、スタックトレースが利用できるようになります。
詳細については、以下のリリースノートを見てください。
内蔵の例外 『冷たい。パフォーマンスの目的のために、そのような例外が数回を投げているときは、この方法は、再コンパイルを行った。再コンパイルすることができる「サーバーVMは現在、すべての正しいスタックバックトレースを提供してコンパイラ』、コンパイラ。-XX::スタックトレースを提供していない事前に割り当てられた例外を使用してより高速な戦術を選択することができ、完全に事前に割り当てられた例外の使用を無効にするには、この新しいフラグを使用します。-OmitStackTraceInFastThrowを」 http://java.sun.com/j2se/1.5.0/relnotes.html の
私はこれを複製することができますが、これはどこかにあなたの行動で何が起こっされるという一種の奇妙なようです。
あなたは空の配列でsetStackTraceを呼び出す場合は、、それはテキストのみが表示される原因となります。
public class Fark {
public static void main(String[] args) {
try {
Fark.throwMe(args.length != 0);
}
catch (Exception e) {
e.printStackTrace();
}
}
public static final void throwMe(boolean arg) throws Exception{
Exception e = new NullPointerException();
if (arg) {
e.setStackTrace(new StackTraceElement[0]);
}
throw e;
}
}
タグ....それを実行します
% java Fark
java.lang.NullPointerException
at Fark.throwMe(Fark.java:15)
at Fark.main(Fark.java:5)
% java Fark nothing
java.lang.NullPointerException