web-dev-qa-db-fra.com

Rapports de crash iOS: atos ne fonctionne pas comme prévu

Je regarde un rapport de plantage fourni par Apple

Hardware Model:      iPhone4,1
Version:         ??? (???)
Code Type:       ARM (Native)
Parent Process:  launchd [1]

Date/Time:       2012-11-18 16:03:44.951 -0600
OS Version:      iOS 6.0.1 (10A523)
Report Version:  104

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x51fe5264
Crashed Thread:  0

Thread 0 name:  Dispatch queue: com.Apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib                 0x352925b0 objc_msgSend + 16
1   MYAPP                           0x0006573a -[MyViewController(Images) didReceiveImage:context:etag:expires:] + 42
2   MYAPP                           0x0004fb26 -[MyImageTask didReceiveImage:] + 98
3   Foundation                      0x361ac8e8 __NSThreadPerformPerform
4   CoreFoundation                  0x3b37d680 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
5   CoreFoundation                  0x3b37cee4 __CFRunLoopDoSources0
6   CoreFoundation                  0x3b37bcb2 __CFRunLoopRun
7   CoreFoundation                  0x3b2eeeb8 CFRunLoopRunSpecific
8   CoreFoundation                  0x3b2eed44 CFRunLoopRunInMode
9   GraphicsServices                0x396bc2e6 GSEventRunModal
10  UIKit                           0x3452e2f4 UIApplicationMain
11  MYAPP                           0x0004934a main + 70
12  MYAPP                           0x000492fc start + 36

Le plus drôle, c'est quand j'utilise atos pour rechercher la ligne de code qui correspond aux emplacements des adresses x0006573a et x0004fb26 J'obtiens une correspondance complètement différente. La sortie atos n'est même pas de la même classe que celle mentionnée dans le journal des plantages (MyViewController, MyImageTask). Au lieu de cela, atos me pointe vers des lignes de code totalement bénignes dans une classe complètement indépendante. J'ai vérifié à nouveau que je travaille avec le dSYM et l'IPA exacts que j'ai soumis à Apple.

Ma commande atos

/Applications/Xcode.app/Contents/Developer/usr/bin/atos -Arch armv7 -o MYAPP.app/MYAPP 0x0004fb26

Même résultat avec/usr/bin/atos et pour armv7s.

Est-ce que quelqu'un d'autre a rencontré ce problème? Pouvez-vous me conseiller? Merci.

58
George Burdell

Vous devez calculer l'adresse à utiliser avec atos, vous ne pouvez pas simplement utiliser celle dans le stacktrace.

symbol address = slide + stack address - load address
  1. La valeur slide est la valeur de vmaddr dans LC_SEGMENT cmd (Surtout c'est 0x1000). Exécutez ce qui suit pour l'obtenir:

    otool -Arch ARCHITECTURE -l "APP_BUNDLE/APP_EXECUTABLE" | grep -B 3 -A 8 -m 2 "__TEXT"
    

    Remplacez ARCHITECTURE par l'architecture réelle que le rapport de plantage montre, par ex. armv7. Remplacer APP_BUNDLE/APP_EXECUTABLE avec le chemin vers l'exécutable réel.

  2. Le stack address est la valeur hexadécimale du rapport de plantage.

  3. Le load address peut être est la première adresse affichée dans le Binary Images section au tout début de la ligne qui contient votre exécutable. (Habituellement, la première entrée).

Étant donné que dans le passé, la valeur de slide était égale à la valeur de load address cela a toujours fonctionné. Mais depuis Apple introduit randomisation de la disposition de l'espace d'adressage à partir d'iOS 4.3 (dans différentes variantes), l'adresse de chargement des applications est aléatoire pour des raisons de sécurité.

90
Kerni

Une alternative plus simple: vous pouvez utiliser le atos -l drapeau pour lui faire faire le calcul pour vous.

Supposons que vous ayez la ligne suivante dans votre journal des plantages que vous souhaitez symboliser:

5   MyApp                   0x0044e89a 0x29000 + 4348058

Le premier numéro hexadécimal est l'adresse de la pile et le deuxième numéro hexadécimal est l'adresse de chargement. Vous pouvez ignorer le dernier numéro. Vous n'avez pas non plus à vous soucier des adresses des diapositives.

Pour symboliser, procédez comme suit:

atos -o MyApp.app/MyApp -Arch armv7 -l 0x29000 0x0044e89a

Si vous ne trouvez pas votre fichier MyApp.app/MyApp, renommez votre fichier '.ipa' en '.Zip', décompressez-le et il sera dans le dossier Payload.

Et si vous n'êtes pas sûr de l'architecture à utiliser (par exemple, armv7 ou armv7s), faites défiler jusqu'à la partie `` Images binaires '' du fichier de crash et vous pouvez le trouver là-dedans.

À votre santé

98
Chris

Utilisez simplement dwarfdump:

dwarfdump --Arch armv7 myApp.dSYM --lookup 0xaabbccdd | grep 'Line table'

Pas besoin de faire de calculs.

(De Obtenir le symbole par adresse (symbolisant le binaire, la construction iOS) ).

11
CpnCrunch

Pour qui certains moments n'ont pas la valeur de l'adresse de chargement comme ceci:

Jan 14 11:02:39 Dennins-iPhone AppName[584] <Critical>: Stack Trace: (
    0   CoreFoundation                      0x2c3084b7 <redacted> + 150
    1   libobjc.A.dylib                     0x39abec8b objc_exception_throw + 38
    2   CoreFoundation                      0x2c21cc35 CFRunLoopRemoveTimer + 0
    3   AppName                             0x0005a7db AppName + 272347  

J'ai créé un bash simple pour m'aider à déboguer:

#! /bin/bash
read -p "[Path] [App Name] [Stack Address] [DecimalSum] " path appName stackAddress decimalSum
loadAddress=`echo "obase=16;ibase=10;$((stackAddress-decimalSum))" | bc`
atos -o $path/Payload/$appName.app/$appName -l $loadAddress $stackAddress -Arch armv7

Il lit simplement le chemin de l'application, le nom de l'application, l'adresse de la pile et la valeur après le signal "+" (la valeur décimale), puis trouve la valeur de l'adresse de chargement pour exécuter la commande atos.

3
DenninDalke