Gibt es eine Möglichkeit, einen Stack-Trace auszugeben, ohne eine Ausnahme in Java auszulösen?

Lesezeit: 4 Minuten

Benutzer-Avatar
corgrath

Ich denke darüber nach, ein Debug-Tool für meine Java-Anwendung zu erstellen.

Ich frage mich, ob es möglich ist, einen Stack-Trace zu erhalten, genau wie Exception.printStackTrace() aber ohne tatsächlich eine Ausnahme auszulösen?

Mein Ziel ist es, in jeder beliebigen Methode einen Stack auszugeben, um zu sehen, wer der Aufrufer der Methode ist.

Benutzer-Avatar
Rob di Marco

Ja, einfach verwenden

Thread.dumpStack()

  • Das ist die Antwort, die die eigentliche Frage beantwortet.

    – Bruno

    10. Juni 2015 um 16:53 Uhr


  • Sehr schlicht und elegant. Dies hätte die akzeptierte Antwort sein sollen.

    – deLock

    8. Mai 2018 um 11:53 Uhr

  • Fwiw, die Quelle dieser Methode: public static void dumpStack() { new Exception("Stack trace").printStackTrace(); }

    – JohannesK

    26. November 2018 um 19:04 Uhr

  • Dies ist bei weitem die beste Antwort auf die Frage, ob Sie mit der Ausgabe zufrieden sind stderrwas die Implikation der Frage zu sein scheint.

    – Mike Nagetier

    2. Mai 2020 um 8:24 Uhr

Benutzer-Avatar
Prabhu R

Sie können es auch versuchen Thread.getAllStackTraces() um eine Karte der Stack-Traces für alle aktiven Threads zu erhalten.​​​​​​

Benutzer-Avatar
Tom Anderson

Wenn Sie die Ablaufverfolgung nur für den aktuellen Thread wünschen (und nicht für alle Threads im System, wie es Rams Vorschlag tut), tun Sie Folgendes:

Thread.aktuellerThread().getStackTrace()

Gehen Sie wie folgt vor, um den Anrufer zu finden:

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

Und rufen Sie diese Methode innerhalb der Methode auf, die wissen muss, wer ihr Aufrufer ist. Aber Achtung: Der Index des aufrufenden Frames innerhalb der Liste kann je nach JVM variieren! Es hängt alles davon ab, wie viele Ebenen von Aufrufen es in getStackTrace gibt, bevor Sie den Punkt erreichen, an dem die Ablaufverfolgung generiert wird. Eine robustere Lösung wäre, die Ablaufverfolgung abzurufen und darüber zu iterieren, um nach dem Frame für getCallingMethodName zu suchen, und dann zwei Schritte weiter nach oben zu gehen, um den wahren Aufrufer zu finden.

  • Erstellen Sie also einfach selbst eine neue Ausnahme und verwenden Sie sie [1] als Index!

    – Daniel

    7. Juli 2011 um 6:21 Uhr

  • Der Titel dieser Frage lautet “ohne eine Ausnahme auszulösen”. Zugegeben, Sie schlagen vor, die Ausnahme zu erstellen, aber nicht zu werfen, aber ich denke immer noch, dass dies nicht im Sinne der Frage ist.

    – Tom Anderson

    7. Juli 2011 um 10:16 Uhr

  • Natürlich ist es das. Das Erstellen einer Ausnahme ist der niedrigste Weg, um einen Stacktrace zu erhalten. Sogar dein Thread.currentThread().getStackTrace() macht es, aber mein Weg macht es schneller :).

    – Daniel

    7. Juli 2011 um 17:19 Uhr


  • @Daniel Es gibt noch eine weitere Überlegung: Bei vielen Test-Frameworks, z. B. Spock, reicht es aus, nur eine Ausnahme zu erstellen (ohne sie auszulösen), damit das Framework aufgreift: Der Test berücksichtigt dann, dass eine Ausnahme “aufgetreten” ist, und der Test wird es tun Ende, mit einem Fehlschlag.

    – Mike Nagetier

    13. April 2018 um 14:06 Uhr


  • @mikerodent: Bist du sicher? Spock würde dafür Agenten einsetzen müssen. Aber wie auch immer, weil ich nur die Klasse aufrufen musste, habe ich Reflection.getCallerClass(2) in einer Hilfsfunktion verwendet. Sie werden die Funktion und die Zeilennummer so nicht erhalten, dachte ich.

    – Daniel

    14. April 2018 um 22:34 Uhr


Sie können einen Stack-Trace wie folgt erhalten:

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

Wenn Sie auf den Frame zugreifen möchten, können Sie t.getStackTrace() verwenden, um ein Array von Stack-Frames zu erhalten.

Beachten Sie, dass diesem Stacktrace (wie jedem anderen) einige Frames fehlen können, wenn der Hotspot-Compiler damit beschäftigt war, Dinge zu optimieren.

Beachten Sie, dass Thread.dumpStack() tatsächlich eine Ausnahme auslöst:

new Exception("Stack trace").printStackTrace();

  • Es wird eine Ausnahme erstellt, aber nicht ausgelöst.

    – Tyler

    18. Februar 2014 um 21:40 Uhr

Benutzer-Avatar
mkobit

Java 9 führte die ein StackWalker und unterstützende Klassen zum Gehen des Stapels.

Hier sind ein paar Ausschnitte aus dem Javadoc:

Das walk -Methode öffnet einen sequentiellen Stream von StackFrames für den aktuellen Thread und wendet dann die angegebene Funktion an, um die zu durchlaufen StackFrame Strom. Der Stream meldet Stack-Frame-Elemente der Reihe nach, vom obersten Frame, der den Ausführungspunkt darstellt, an dem der Stack generiert wurde, bis zum untersten Frame. Das StackFrame stream wird geschlossen, wenn die walk-Methode zurückkehrt. Wenn versucht wird, den geschlossenen Stream wiederzuverwenden, IllegalStateException wird geworfen.

  1. Um einen Schnappschuss der obersten 10 Stack-Frames des aktuellen Threads zu machen,

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

  • Es wird eine Ausnahme erstellt, aber nicht ausgelöst.

    – Tyler

    18. Februar 2014 um 21:40 Uhr

Benutzer-Avatar
Andreas Newdigate

Sie können auch ein Signal an die JVM senden, um Thread.getAllStackTraces() auf einem laufenden Java-Prozess auszuführen, indem Sie ein QUIT-Signal an den Prozess senden.

Verwenden Sie unter Unix/Linux:

kill -QUIT process_idwobei process_id die Prozessnummer Ihres Java-Programms ist.

Unter Windows können Sie in der Anwendung Strg-Umbruch drücken, obwohl Sie dies normalerweise nicht sehen werden, es sei denn, Sie führen einen Konsolenprozess aus.

JDK6 hat eine weitere Option eingeführt, den jstack-Befehl, der den Stack von jedem laufenden JDK6-Prozess auf Ihrem Computer anzeigt:

jstack [-l] <pid>

Diese Optionen sind sehr nützlich für Anwendungen, die in einer Produktionsumgebung ausgeführt werden und nicht einfach geändert werden können. Sie sind besonders nützlich für die Diagnose von Laufzeit-Deadlocks oder Leistungsproblemen.

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

1352660cookie-checkGibt es eine Möglichkeit, einen Stack-Trace auszugeben, ohne eine Ausnahme in Java auszulösen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy