Question Instructions d'analyse Spindump?


J'ai une collection de piles concentrées sur une application qui doit être analysée, mais je ne sais pas exactement comment les analyser. J'ai vu d'autres développeurs capables de les analyser rapidement, soit mentalement, soit avec un logiciel, et de me revenir avec des détails sur la façon dont les blocages viennent et ainsi de suite, et j'espère comprendre comment les analyser correctement.

Où va-t-on pour analyser correctement les spindumps?


13
2018-05-22 20:21


origine


Réponses:


Généralement:

  • avec un rapport de panne, vous obtenez une trace de pile
  • avec spindumps, vous obtenez plusieurs traces de pile sur une période donnée.

Il y a deux cas dans lesquels vous pourriez vouloir examiner un spindump:

  1. une boucle infinie, appelant probablement la même fonction encore et encore
  2. impasse.

Le premier cas peut être vu de la broche par de nombreux appels à la même fonction encore et encore. Le moniteur d'activité est une bonne chose à utiliser dans de telles situations: prenez un échantillon d'un processus bloqué et vous pouvez le visualiser de plusieurs manières utiles, en masquant des cadres sans importance, etc.

Le second cas peut être visualisé par différents threads attendant des verrous en même temps.

Voici un petit exemple:

+ 2663 start  (in MyApp) + 52  [0x100001bb4]
+   2663 main  (in MyApp) + 39  [0x100001be7]  main.m:65
+     2663 NSApplicationMain  (in AppKit) + 869  [0x7fff8ea27cb6]
+       2663 -[NSApplication run]  (in AppKit) + 517  [0x7fff8ea83283]
+         2663 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]  (in AppKit) + 128  [0x7fff8ea8bed2]
+           2663 _DPSNextEvent  (in AppKit) + 685  [0x7fff8ea8c613]
+             2663 BlockUntilNextEventMatchingListInMode  (in HIToolbox) + 62  [0x7fff8dd53cd3]
+               2663 ReceiveNextEventCommon  (in HIToolbox) + 356  [0x7fff8dd53e42]
+                 2663 RunCurrentEventLoopInMode  (in HIToolbox) + 209  [0x7fff8dd540a4]
+                   2663 CFRunLoopRunSpecific  (in CoreFoundation) + 290  [0x7fff95dec6b2]
+                     2557 __CFRunLoopRun  (in CoreFoundation) + 1078  [0x7fff95decee6]
+                     ! 2556 __CFRunLoopServiceMachPort  (in CoreFoundation) + 195  [0x7fff95de7803]
+                     ! : 2556 mach_msg  (in libsystem_kernel.dylib) + 70  [0x7fff93630c42]
+                     ! :   2556 mach_msg_trap  (in libsystem_kernel.dylib) + 10  [0x7fff93631686]
+                     ! 1 __CFRunLoopServiceMachPort  (in CoreFoundation) + 199  [0x7fff95de7807]
+                     97 __CFRunLoopRun  (in CoreFoundation) + 728  [0x7fff95decd88]
+                     ! 97 __CFRunLoopDoObservers  (in CoreFoundation) + 369  [0x7fff95e11921]
+                     !   97 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__  (in CoreFoundation) + 23  [0x7fff95e119b7]
+                     !     97 __83-[NSWindow _postWindowNeedsDisplayOrLayoutOrUpdateConstraintsUnlessPostingDisabled]_block_invoke_01208  (in AppKit) + 46  [0x7fff8f05a971]
+                     !       90 _handleWindowNeedsDisplayOrLayoutOrUpdateConstraints  (in AppKit) + 738  [0x7fff8ea8f2ac]
+                     !       : 89 -[NSView displayIfNeeded]  (in AppKit) + 1830  [0x7fff8ea8fd73]

Qu'est-ce que cela me dit, est-ce que MyApp a traversé main, etc. et a finalement obtenu une fonction CFRunLoopRunSpecific, puis __CFRunLoopRun - de là (2557) a appelé __CFRunLoopServiceMachPortqui a appelé mach_msg et est entré dans un piège à mach_msg_trap (appelant un appel syscall) - à son retour, la trace de la pile est revenue à CFRunLoopRunSpecific, où __CFRunLoopRun a été appelé, qui appelle alors __CFRunLoopDoObservers, etc.

Notez qu'il ne s'agit pas d'une copie d'un processus en suspens - vous pouvez échantillonner de cette manière tout processus en cours d'exécution et afficher les fonctions appelées pendant cet échantillon. Une boucle infinie, cependant, répétera les appels à une fonction encore et encore - il y aura le même arbre d'appel encore et encore. Bien sûr, cela peut signifier un simple cycle, mais c'est là que vous pouvez examiner si le cycle n'est pas pour une raison infinie. Malheureusement, ces dumps spin sont généralement assez longs, en fonction de la fonction que vous appelez, il peut donc falloir un certain temps pour examiner

Le signe + au début de la ligne indique simplement un début de ligne - les lignes sans le signe + indiquent le début d'un nouveau thread. Le ! et: les signes forment une ligne, il est donc plus facile pour vous de voir les appels suivants - c'est-à-dire quels appels sont au même niveau. En outre, | caractère peut également être utilisé.

Les nombres signifient combien de temps l'application a passé dans cet appel particulier - ils sont dans le nombre d'échantillons. L'échantillonnage fonctionne si l'application échantillonnée est suspendue toutes les quelques millisecondes et que le cadre de la pile est examiné de chaque thread. Si l'application est toujours dans la même fonction, la fonction obtient +1.


11
2017-11-20 22:27



J'ai trouvé cela lors de la recherche des ressources de développeur Mac pour «spindump». Je n'en ai jamais vu, mais cette TechNote mentionnée dans la page de manuel de ReportCrash (8) semble vous montrer comment lire les journaux de crash:

https://developer.apple.com/library/mac/#technotes/tn2004/tn2123.html

Et ReportCrash (8) s'est référé à Spindump (8), mes excuses. https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/ReportCrash.8.html

Mais apparemment, cela ne vous aide pas. Je vais tout laisser ici.

J'espère que cela aidera quelqu'un en quelque sorte.


1
2017-11-16 09:36