37 votes

Comment lire les traces de pile d'Objective-C

J'ai la trace de pile suivante :

0 MyApp 0x000833a3 +[TFCrashHandler backtrace] + 26
1 MyApp 0x000836bd TFSignalHandler + 28
2 libsystem_c.dylib 0x33eac727 _sigtramp + 34
3 ??? 0x00000002 0x0 + 2
4 MyApp 0x000803f1 msgpack_unpack_next + 112
5 MyApp 0x0007faeb +[MessagePackParser parseData:] + 74
6 MyApp 0x0007f84b -[NSData(NSData_MessagePack) messagePackParse] + 26
7 MyApp 0x000254c3 +[Http get:params:cacheMins:msgPack:complete:] + 146
...

Et je me demande comment le lire :

  • Je suppose que je vais du bas vers le haut, par exemple la ligne 7 appelée ligne 6 appelée ligne 5, etc.
  • Que signifie le "+ 112" de la ligne 4 ? Est-ce un numéro de ligne dans le fichier de code où il s'est planté ?
  • Que signifie le " ???" de la ligne 3 ?

Merci beaucoup.

61voto

bbum Points 124887
0 MyApp 0x000833a3 +[TFCrashHandler backtrace] + 26

Le crash a été généré à partir de +[TFCrashHandler backtrace] + 26 ; de n'importe quelle instruction tombée à cet emplacement de symbole + 26 octets.

Si c'est vraiment le bas de votre trace de pile et qu'il s'est planté là, alors le TCrashHandler masque le véritable accident. Le vrai accident semble être quelques images plus haut.

1 MyApp 0x000836bd TFSignalHandler + 28

TFSignalHandler est ce qui a été appelé +backtrace.

2 libsystem_c.dylib 0x33eac727 _sigtramp + 34

Ewww... un signal trampoline. L'application a reçu un signal et le trampoline a été configuré pour appeler TFSignalHandler().

Il existe des situations où un gestionnaire de signal peut être appelé sur un thread aléatoire. C'est-à-dire qu'il y a une chance minuscule que ce crash particulier n'ait rien à voir avec le parseur et tout à voir avec un crash ailleurs. Cependant, sans en savoir plus sur l'analyseur syntaxique, je me demande s'il est renforcé contre les entrées malveillantes (qui pourraient certainement provoquer un tel crash).

3 ??? 0x00000002 0x0 + 2

La pile était indécodable. Ignorer. Sans signification. Meilleur cas ; retombées de l'optimisation du compilateur. Pire cas ; quelqu'un a fait caca sur la pile et le mécanisme de backtrace ne peut pas comprendre ce qui se passe (hautement improbable -- habituellement, le caca de la pile éclabousse au point d'empêcher un backtrace complet).

4 MyApp 0x000803f1 msgpack_unpack_next + 112

Ooooh... rusé. Quelqu'un utilise le C pour analyser des trucs. Et il s'est écrasé. L'instruction qui se trouvait à 112 octets du point d'entrée de la fonction a disparu. flèche . Mais, pas vraiment, parce qu'il a appelé le gestionnaire de signal et a été traité par celui-ci ; ce qui est toujours un flèche mais le gestionnaire du signal a effectivement détruit d'autres preuves médico-légales.

Le commentaire "trickzy" fait référence au fait qu'un compilateur optimisant un gros tas de C peut finir par réduire les cadres au point que le crash aurait pu se produire dans une fonction bien inférieure à celle-ci.

5 MyApp 0x0007faeb +[MessagePackParser parseData:] + 74

MessagePackParser était en train d'analyser quand les choses ont mal tourné.

6 MyApp 0x0007f84b -[NSData(NSData_MessagePack) messagePackParse] + 26
7 MyApp 0x000254c3 +[Http get:params:cacheMins:msgPack:complete:] + 146

Ahh... oui.... quelqu'un a récupéré des données sur HTTP et elles étaient malformées, ce qui a provoqué le crash.

En résumé, l'analyseur a reçu une fausse entrée et s'est planté. Il y avait un gestionnaire de signal en place qui a essayé d'aider en créant un backtrace, mais -- apparemment -- n'a pas vraiment révélé plus d'informations. Une alternative possible est que le signal a été généré ailleurs et que ce thread a été choisi au hasard pour le gérer -- si vous pouvez recréer ce crash de manière cohérente, le cas du signal aléatoire du thread est peu probable.

À moins que vous n'ayez une capture des données d'entrée ou que vous puissiez deviner comment msgpack_unpack_next() pourrait planter, vous n'avez pas de chance sans fournir plus d'informations.

3voto

ThomasW Points 8078

Le " ???" est quelque chose qui ne peut pas être identifié, probablement un code qui a été compilé sans symboles, mais qui pourrait aussi être autre chose.

-2voto

bdparrish Points 1476

Ce sont les numéros de ligne dans le fichier d'implémentation. Et l'hex est le pointeur en mémoire de l'appel de ligne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X