Sous Android (Java), comment imprimer une trace de pile complète? Si mon application se bloque à partir de nullPointerException ou de quelque chose, elle imprime une trace de pile (presque) complète comme ceci:
java.io.IOException: Attempted read from closed stream.
com.android.music.sync.common.SoftSyncException: java.io.IOException: Attempted read from closed stream.
at com.android.music.sync.google.MusicSyncAdapter.getChangesFromServerAsDom(MusicSyncAdapter.java:545)
at com.android.music.sync.google.MusicSyncAdapter.fetchDataFromServer(MusicSyncAdapter.java:488)
at com.android.music.sync.common.AbstractSyncAdapter.download(AbstractSyncAdapter.java:417)
at com.android.music.sync.common.AbstractSyncAdapter.innerPerformSync(AbstractSyncAdapter.java:313)
at com.android.music.sync.common.AbstractSyncAdapter.onPerformLoggedSync(AbstractSyncAdapter.java:243)
at com.google.android.common.LoggingThreadedSyncAdapter.onPerformSync(LoggingThreadedSyncAdapter.java:33)
at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:164)
Caused by: java.io.IOException: Attempted read from closed stream.
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:148)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:159)
at java.util.zip.GZIPInputStream.readFully(GZIPInputStream.java:212)
at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:81)
at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:64)
at android.net.http.AndroidHttpClient.getUngzippedContent(AndroidHttpClient.java:218)
at com.android.music.sync.api.MusicApiClientImpl.createAndExecuteMethod(MusicApiClientImpl.java:312)
at com.android.music.sync.api.MusicApiClientImpl.getItems(MusicApiClientImpl.java:588)
at com.android.music.sync.api.MusicApiClientImpl.getTracks(MusicApiClientImpl.java:638)
at com.android.music.sync.google.MusicSyncAdapter.getChangesFromServerAsDom(MusicSyncAdapter.java:512)
... 6 more
Cependant, parfois, à des fins de débogage, je souhaite enregistrer une trace de pile complète d'où je suis dans le code. J'ai pensé que je pouvais simplement faire ceci:
StackTraceElement trace = new Exception().getStackTrace();
Log.d("myapp", trace.toString());
Mais cela imprime juste le pointeur vers l'objet ... Dois-je parcourir tous les éléments traces de la pile pour les imprimer? Ou existe-t-il une méthode simple pour tout imprimer?
Réponses:
Il y a des remplacements de toutes les méthodes de journal avec des
(String tag, String msg, Throwable tr)
signatures.Passer une exception comme troisième paramètre devrait vous donner le stacktrace complet dans logcat.
la source
getStackTraceString()
méthode mentionnée par @Thomas dans les coulisses.Ce qui suit devrait faire l'affaire:
Notez qu'à
...x more
la fin ne coupe aucune information de la trace de la pile:... ou en d'autres termes, remplacer
x more
par les dernièresx
lignes de la première exception.la source
getStackTraceString()
? N'apparaît pas dans Eclipse? Cela ne fait pas partie deThrowable
ouException
....import android.util.Log;
).Utilisez Log.getStackTraceString (Throwable t). Vous pouvez obtenir des traces de pile plus longues en creusant plus profondément. Par exemple:
Extrait de http://developer.android.com/reference/android/util/Log.html#getStackTraceString%28java.lang.Throwable%29
la source
Log.getStackTraceString()
ne consigne pas la trace de la pile, il la renvoie simplement sous forme de chaîne. Le code ci-dessus ne consignera rien et échouera également avec un NPE sie.getCause()
c'est le casnull
.la source
Vous pouvez utiliser ceci:
la source
Vous pouvez également imprimer une trace de pile à tout moment dans le code de votre application à l'aide de méthodes telles que
Thread.dumpStack()
Veuillez parcourir le lien pour plus de détails
la source
Vous devez utiliser Throwable Object pour obtenir le stackTrace complet.
Réf: https://stackoverflow.com/a/18546861
la source
J'ai rapidement fait une fonction récursive qui itérera le throwable et throwable.getCause ().
C'est parce que chaque "throwable.getCause ()" vous renvoie un nouveau message d'exception avec quelques lignes répétées et de nouvelles lignes. Donc, le concept est: s'il y a une "cause", il y a une ligne avec "n plus .." sur le jetable principal donc j'obtiens la dernière ligne avant celle avec "n plus .." alors j'obtiens le message de cause et enfin, je sous-chaîne le message de cause ne récupérant que la partie après la dernière ligne répétée (la dernière ligne qui apparaît sur les deux: le jetable principal et le jetable de cause).
Ensuite, j'utilise la récursivité lorsque j'obtiens le message de cause, donc en réappelant la même fonction pour obtenir le message de cause du jetable principal, j'obtiendrai un message déjà remplacé. Si la cause jetable du jetable principal a également une autre cause, donc le jetable principal a 3 niveaux (main -> cause -> cause-of-cause), sur le jetable principal, j'obtiendrai un message de cause, un message déjà remplacé (en utilisant le même concept de la principale
Je l'ai essayé uniquement avec 2 niveaux (principal -> cause) et pas avec plus: / S'il y a quelque chose qui ne va pas, veuillez modifier la fonction et écrire un commentaire: D
bonne programmation et bonne journée aussi: D
Important:
Ce code obtient parfois une exception si le "st" ne contient pas "\ n" ou similaire (j'ai trouvé que certaines sortes d'exceptions stacktraces ont ce problème). Pour résoudre ce problème, vous devez ajouter une vérification avant la ligne de code: "String r1 = ..."
Vous devez vérifier: "st" contient "\ n" et que les index de début et de fin de "st.subSequence" sont tous les deux valides.
Quoi qu'il en soit, je suggère de mettre cela dans un try-catch et de retourner une chaîne vide en cas d'exception. (Il est récursif donc la chaîne vide renvoyée sera concaténée à la chaîne traitée précédente).
la source