Existe-t-il un moyen de vider une trace de stack sans lancer une exception dans Java?

Je pense à créer un outil de débogage pour mon application Java.

Je me demande s’il est possible d’obtenir une trace de stack, tout comme Exception.printStackTrace() mais sans réellement lancer une exception?

Mon but est, dans toute méthode donnée, de vider une stack pour voir qui est l’appelant de la méthode.

Vous pouvez également essayer Thread.getAllStackTraces() pour obtenir une carte des traces de stack pour tous les threads qui sont actifs.

Oui, utilisez simplement

 Thread.dumpStack() 

Si vous voulez la trace du thread actuel (plutôt que tous les threads du système, comme le fait la suggestion de Ram), faites:

Thread.currentThread (). getStackTrace ()

Pour trouver l’appelant, faites:

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

Et appelez cette méthode depuis la méthode qui doit savoir qui est l’appelant. Cependant, un mot d’avertissement: l’index de la trame d’appel dans la liste pourrait varier selon la JVM! Tout dépend du nombre de couches d’appels dans getStackTrace avant que vous n’atteigniez le point où la trace est générée. Une solution plus robuste consisterait à obtenir la trace et à la parcourir à la recherche du cadre de getCallingMethodName, puis à franchir deux étapes pour trouver le véritable appelant.

Vous pouvez obtenir une trace de stack comme ceci:

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

Si vous souhaitez accéder au cadre, vous pouvez utiliser t.getStackTrace () pour obtenir un tableau de frameworks de stack.

Sachez que cette stacktrace (comme n’importe quel autre) peut manquer de certains frameworks si le compilateur de hotspot a été occupé à optimiser les choses.

Notez que Thread.dumpStack () lève effectivement une exception:

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

Vous pouvez également envoyer un signal à la JVM pour exécuter Thread.getAllStackTraces () sur un processus Java en cours d’exécution en envoyant un signal QUIT au processus.

Sous Unix / Linux, utilisez:

kill -QUIT process_id , où process_id est le numéro de processus de votre programme Java.

Sous Windows, vous pouvez appuyer sur Ctrl-Break dans l’application, mais vous ne le verrez généralement pas, sauf si vous exécutez un processus de console.

JDK6 a introduit une autre option, la commande jstack, qui affichera la stack à partir de tout processus JDK6 en cours d’exécution sur votre ordinateur:

jstack [-l]

Ces options sont très utiles pour les applications qui s’exécutent dans un environnement de production et ne peuvent pas être modifiées facilement. Ils sont particulièrement utiles pour diagnostiquer les blocages d’exécution ou les problèmes de performance.

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

Si vous avez besoin d’une sortie de capture

 SsortingngWriter sw = new SsortingngWriter(); new Throwable("").printStackTrace(new PrintWriter(sw)); Ssortingng stackTrace = sw.toSsortingng(); 

Java 9 a introduit StackWalker et les classes de support pour parcourir la stack.

Voici quelques extraits du Javadoc:

La méthode walk ouvre un stream séquentiel de StackFrames pour le thread en cours, puis applique la fonction donnée pour parcourir le stream StackFrame . Le stream rapporte les éléments de cadre de stack dans l’ordre, à partir du cadre le plus en haut qui représente le point d’exécution auquel la stack a été générée dans le cadre le plus bas. Le stream StackFrame est fermé lorsque la méthode Walk retourne. Si une tentative est faite pour réutiliser le stream fermé, une IllegalStateException sera lancée.

  1. Pour photographier les 10 premiers frameworks de stack du thread en cours,

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

HPROF Java Profiler

Vous n’avez même pas à le faire dans le code. Vous pouvez attacher le fichier HPROF Java à votre processus et à tout moment, appuyez sur Control- \ pour générer un vidage de tas, exécuter des threads, etc. . . sans brouiller votre code d’application. C’est un peu dépassé, Java 6 est livré avec l’interface graphique, mais je trouve toujours que HPROF est très utile.