web-dev-qa-db-ja.com

Javaで例外をスローせずにスタックトレースをダンプする方法はありますか?

Javaアプリケーション用のデバッグツールを作成することを考えています。

Exception.printStackTrace()のように、しかし実際に例外をスローせずに、スタックトレースを取得できるかどうか疑問に思っていますか?

私の目標は、特定のメソッドでスタックをダンプして、メソッドの呼び出し元を確認することです。

140
corgrath

Thread.getAllStackTraces()を試して、生きているすべてのスレッドのスタックトレースのマップを取得することもできます。

78
Prabhu R

はい、単に使用します

Thread.dumpStack()
219
Rob Di Marco

(Ramの提案のように、システム内のすべてのスレッドではなく)現在のスレッドのみのトレースが必要な場合は、次のようにします。

Thread.currentThread(). getStackTrace()

呼び出し元を見つけるには、次を実行します。

private String getCallingMethodName() {
    StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4];
    return callingFrame.getMethodName();
}

そして、呼び出し元を知る必要があるメソッド内からそのメソッドを呼び出します。ただし、警告の言葉:リスト内の呼び出しフレームのインデックスは、JVMによって異なる場合があります!それはすべて、トレースが生成されるポイントに到達する前にgetStackTrace内にある呼び出しの層の数に依存します。より堅牢なソリューションは、トレースを取得し、getCallingMethodNameのフレームを探してそれを反復処理し、さらに2つのステップを実行して真の呼び出し元を見つけることです。

39
Tom Anderson

次のようなスタックトレースを取得できます。

Throwable t = new Throwable();
t.printStackTrace();

フレームにアクセスする場合は、t.getStackTrace()を使用してスタックフレームの配列を取得できます。

ホットスポットコンパイラが最適化に忙しい場合は、このスタックトレース(他のフレームワークと同様)で一部のフレームが失われる可能性があることに注意してください。

33
Gerco Dries

Thread.dumpStack()が実際に例外をスローすることに注意してください。

new Exception("Stack trace").printStackTrace();
14
Ariel T

QUITシグナルをプロセスに送信することにより、実行中のJavaプロセスでThread.getAllStackTraces()を実行するJVMにシグナルを送信することもできます。

Unix/Linuxの場合:

kill -QUIT process_id、ここでprocess_idは、Javaプログラムのプロセス番号です。

Windowsでは、アプリケーションでCtrl-Breakを押すことができますが、通常はコンソールプロセスを実行していない限り表示されません。

JDK6では、jstackコマンドという別のオプションが導入されました。このオプションは、コンピューターで実行中のJDK6プロセスのスタックを表示します。

jstack [-l] <pid>

これらのオプションは、実稼働環境で実行されており、簡単に変更できないアプリケーションに非常に役立ちます。これらは、実行時のデッドロックやパフォーマンスの問題を診断するのに特に役立ちます。

http://Java.Sun.com/developer/technicalArticles/Programming/Stacktrace/http://Java.Sun.com/javase/6/docs/technotes/tools/share /jstack.html

6

Java 9は StackWalker を導入し、スタックを歩くためのクラスをサポートしました。

Javadocのスニペットを次に示します。

walk メソッドは、現在のスレッドに対して StackFrames の順次ストリームを開き、指定された関数を適用してStackFrameストリーム。ストリームは、スタックが生成された実行ポイントを表す一番上のフレームから一番下のフレームまで、順番にスタックフレーム要素を報告します。 walkメソッドが戻ると、StackFrameストリームは閉じられます。閉じたストリームを再利用しようとすると、IllegalStateExceptionがスローされます。

...

  1. 現在のスレッドのトップ10スタックフレームのスナップショットを作成するには、

    List<StackFrame> stack = StackWalker.getInstance().walk(s ->
     s.limit(10).collect(Collectors.toList()));
    
4
mkobit

キャプチャ出力が必要な場合

StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
4

HPROF Java Profiler

コードでこれを行う必要さえありません。 Java HPROFをプロセスにアタッチし、任意の時点でControl- \を押すと、ヒープコード、実行中のスレッドなどを出力できます。 、Java 6はGUI jconsoleに付属していますが、HPROFは非常に便利であると感じています。

0
Gandalf