2015-12-08 9 views
5

Obiettivo:Come "manualmente" symbolicate [NSThread callStackSymbols] (ottenere l'indirizzo di partenza per Atos) (iOS)

voglio symbolicate la "produzione" di [NSThread callStackSymbols].

Note

collaterali:

so come fare con i resoconti di blocco. Tuttavia, ho bisogno di indagare su alcuni problemi in cui vorrei vedere lo stack delle chiamate. Purtroppo in questi giorni gli indirizzi del framework sono tutti <redacted>. Causare un incidente ai punti giusti (o alla fine - vedere la fine della mia domanda) non è davvero accettabile, ma se non riesco a trovare un'altra soluzione, sarà la strada da percorrere.

Devo eseguire i miei test su un dispositivo, quindi non posso usare il simulatore.

approccio attuale:

Quando chiamo questo:

NSLog(@"call stack:\n%@", [NSThread callStackSymbols]); 

ottengo questo output:

2015-12-08 15:04:03.888 Conversion[76776:4410388] call stack: 
(
    0 Conversion       0x000694b5 -[ViewController viewDidLoad] + 128 
    1 UIKit        0x27259f55 <redacted> + 1028 
    ... 
    9 UIKit        0x274f67a7 <redacted> + 134 
    10 FrontBoardServices     0x2b358ca5 <redacted> + 232 
    11 FrontBoardServices     0x2b358f91 <redacted> + 44 
    12 CoreFoundation      0x230e87c7 <redacted> + 14 
    ... 
    16 CoreFoundation      0x23038ecd CFRunLoopRunInMode + 108 
    17 UIKit        0x272c7607 <redacted> + 526 
    18 UIKit        0x272c22dd UIApplicationMain + 144 
    19 Conversion       0x000767b5 main + 108 
    20 libdyld.dylib      0x34f34873 <redacted> + 2 
) 

("Conversione" in questa uscita è l'applicazione.)

Ora posso usare questo comando per "simbolicare" annuncio abiti:

xcrun atos -o /path/to/Conversion.app -arch arm64 -l 0x0??? 

Run come quella (ovviamente con un valore corretto per -l), posso inserire gli indirizzi come 0x000694b5 e sarà sputare fuori qualcosa come -[ViewController viewDidLoad] + 128. Ovviamente il problema è l'indirizzo di partenza (il valore dell'opzione -l).

Quando ho un registro di crash, posso ottenerlo. Tuttavia, mi piacerebbe andare via senza un incidente.

Domande:

Q1: Posso determinare l'indirizzo iniziale in fase di esecuzione e forse includerlo nel registro di uscita in modo da posso dargli da mangiare per l'opzione Atos -l?

EDIT: Sembra che questo è possibile in questo modo: (grazie a NSProgrammer per risposta https://stackoverflow.com/a/12464678/1396265)

#import <mach-o/dyld.h> 

... 
intptr_t slide = _dyld_get_image_vmaddr_slide(0); 
const struct mach_header * load_addr = _dyld_get_image_header(0); 
NSLog(@"slide %lx load addr %lx", (long)slide, (long)load_addr); 

/EDIT

(Come io sono interessato a chiamate di metodo del quadro, certamente bisogno gli indirizzi iniziali dei framework. L'indirizzo iniziale dell'app cambia frequentemente (randomizzazione), non lo so ancora, indipendentemente dal fatto che gli indirizzi iniziali del framework siano randomizzati.)

Q2: Esistono altri approcci per indagare i metodi nello stack di chiamate? (I punti di interruzione sono anche piuttosto goffi nel mio scenario.)

EDIT:

Q3: Come posso symbolicate gli indirizzi dei quadri? Ad esempio, dove posso trovare il dSYM (o qualsiasi altra cosa) per UIKit?

(Per esempio ho qualcosa a:. ~/Library/Developer/Xcode/iOS\ DeviceSupport/9.1\ \(13B143\)/Symbols/System/Library/Frameworks/UIKit.framework/ Cercherò in maggiori dettagli qui.)

/EDIT

Forse una soluzione:

Un modo potrebbe essere, a salva l'output del registro in un file e alla fine dei test provoca un arresto anomalo nell'app. In questo modo il registro degli arresti anomali rivelerebbe gli indirizzi iniziali e con le informazioni sullo stack delle chiamate dai log dovrei essere in grado di simboleggiare l'output callStackSymbols. Ci proverò dopo.

+0

Ci sono alcuni modi per fare questo, se symbolicatecrash non funziona, tra cui Atos, dwarfdump e lldb. C'è una bella recensione su un processo di simbolizzazione completo [qui] (https://www.apteligent.com/developer-resources/symbolicating-an-ios-crash-report/?partner_code=GDC_so_symbolicateios) che potrebbe essere di qualche aiuto aggiuntivo – cjbeauchamp

risposta

3

L'aggiunta di frammenti di registro al registro degli arresti anomali ha funzionato bene finora, quindi per ora aggiungerò questa risposta. (Risposte migliori sono sicuramente i benvenuti :-))

Preparazioni:

Aggiungi callStackSymbols registrazione nei punti pertinenti nel codice sorgente:

NSLog(@"call stack:\n%@", [NSThread callStackSymbols]); 

Fai il crollo applicazione (per esempio quando un certo schermo si apre): output di registrazione

strcpy(0, "000"); 

reindirizzamento a un file:

FILE *logfile = freopen([pathForLog cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr); 

Esecuzione:

in Xcode eseguire l'applicazione una sola volta, in modo che viene installato sul dispositivo, e poi fermarlo. Quindi avviare l'app direttamente sul dispositivo, in modo che Xcode non si blocchi.

Utilizzare l'app in modo che lo stack di chiamate sia registrato (può essere molte volte).

Eventualmente fare l'arresto anomalo dell'app (nel mio caso, aprire una determinata schermata che chiama il cattivo strcpy).

Ottenere i file:

In Xcode aperto "Finestra -> Dispositivi", selezionare il dispositivo, selezionare l'applicazione e scarica il contenitore app, in modo che il file di log possono essere estratti.

Nella stessa schermata aprire i registri del dispositivo ed esportare il registro degli arresti anomali.

In Xcode apri "Finestra -> Progetti", seleziona il progetto e falla mostrare la cartella dei dati derivati ​​nel Finder (piccolo pulsante a freccia a destra del percorso dati derivato). Nella cartella dei dati derivati ​​passare a "Build/Products/Debug-iphoneos /" e copiare MyApp.app e MyApp.app.dSYM.

Regolare il registro blocchi:

Per me ha funzionato per aggiungere sezioni di filo in più a destra prima di "Immagini binarie:". Quindi trova la posizione di "Immagini binarie:". Inserire una riga "Thread 9999:". Copia & incollare i discariche stack di chiamate e rimuovere le principali colonne spazi bianchi in modo che assomiglia a questo:

2015-12-09 15:28:58.971 MyApp[21376:3050653] call tree (
Thread 9999: 
0 MyApp        0x00000001001d95f8 -[MyClass myMethod:] + 100 
1 UIKit        0x000000018a5fc2ac <redacted> + 172 
2 UIKit        0x000000018a5d5ca4 <redacted> + 88 
3 UIKit        0x000000018a5d5b8c <redacted> + 460 
4 UIKit        0x000000018a5d5cc0 <redacted> + 116 
5 UIKit        0x000000018a5d5b8c <redacted> + 460 
6 UIKit        0x000000018a5d5cc0 <redacted> + 116 
7 UIKit        0x000000018a5d5b8c <redacted> + 460 
8 UIKit        0x000000018a8e85ac <redacted> + 460 
9 UIKit        0x000000018a5d4abc <redacted> + 96 
10 UIKit        0x000000018a935b7c <redacted> + 344 
11 UIKit        0x000000018a9306f8 <redacted> + 124 
12 UIKit        0x000000018aa584d8 <redacted> + 44 
13 UIKit        0x000000018a933d9c <redacted> + 188 
14 UIKit        0x000000018a70b668 <redacted> + 116 
15 UIKit        0x000000018a70b454 <redacted> + 252 
16 UIKit        0x000000018a70af38 <redacted> + 1404 
17 UIKit        0x000000018a70a9a8 <redacted> + 124 
18 UIKit        0x000000018a616d3c <redacted> + 312 
19 UIKit        0x000000018a616bc4 <redacted> + 108 
20 QuartzCore       0x0000000189dddc2c <redacted> + 284 
21 libdispatch.dylib     0x000000019a3a96a8 <redacted> + 16 
22 libdispatch.dylib     0x000000019a3aedb0 _dispatch_main_queue_callback_4CF + 1844 
23 CoreFoundation      0x00000001850001f8 <redacted> + 12 
24 CoreFoundation      0x0000000184ffe060 <redacted> + 1628 
25 CoreFoundation      0x0000000184f2cca0 CFRunLoopRunSpecific + 384 
26 GraphicsServices     0x000000018ff94088 GSEventRunModal + 180 
27 UIKit        0x000000018a644ffc UIApplicationMain + 204 
28 MyApp        0x0000000100093918 main + 124 
29 libdyld.dylib      0x000000019a3da8b8 <redacted> + 4 

Binary Images: 
... 

Il "filo 9999:" linea rende lo script symbolicatecrash vuole symbolicate prossime righe. Ho scelto 9999 quindi so che queste erano le mie sezioni aggiunte.

Run symbolication:

trovare lo script symbolicatecrash:

$ find /Applications/Xcode.app -name symbolicatecrash -type f 
/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash 
$ 

Il comando symbolication va quasi come questo:

$ symbolicatecrash myapp.crash MyApp.app.dSYM > myapp-sym.crash 

è necessario impostare DEVELOPER_DIR e anteporre il percorso lo script, quindi alla fine assomiglia a questo:

$ DEVELOPER_DIR='/Applications/Xcode.app/Contents/Developer' /Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash myapp.crash MyApp.app.dSYM > myapp-sym.crash 

o avvolto per una migliore piacere di osservazione:

$ DEVELOPER_DIR='/Applications/Xcode.app/Contents/Developer' ... 
/Applications/Xcode.app/Contents/SharedFrameworks/ ... 
DTDeviceKitBase.framework/Versions/A/Resources/ ... 
symbolicatecrash myapp.crash MyApp.app.dSYM > myapp-sym.crash 

Il risultato:

I frammenti symbolicated ora apparire così:

2015-12-09 15:28:58.971 MyApp[21376:3050653] call tree (
Thread 9999: 
0 MyApp        0x00000001001d95f8 -[MyClass myMethod:] (MyFile.m:15) 
1 UIKit        0x000000018a5fc2ac -[UIScrollView _willMoveToWindow:] + 172 
2 UIKit        0x000000018a5d5ca4 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 88 
3 UIKit        0x000000018a5d5b8c -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 460 
4 UIKit        0x000000018a5d5cc0 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 116 
5 UIKit        0x000000018a5d5b8c -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 460 
6 UIKit        0x000000018a5d5cc0 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 116 
7 UIKit        0x000000018a5d5b8c -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 460 
8 UIKit        0x000000018a8e85ac __UIViewWillBeRemovedFromSuperview + 460 
9 UIKit        0x000000018a5d4abc -[UIView(Hierarchy) removeFromSuperview] + 96 
10 UIKit        0x000000018a935b7c __71-[UIPresentationController _initViewHierarchyForPresentationSuperview:]_block_invoke596 + 344 
11 UIKit        0x000000018a9306f8 -[UIPresentationController transitionDidFinish:] + 124 
12 UIKit        0x000000018aa584d8 -[_UICurrentContextPresentationController transitionDidFinish:] + 44 
13 UIKit        0x000000018a933d9c __56-[UIPresentationController runTransitionForCurrentState]_block_invoke_2 + 188 
14 UIKit        0x000000018a70b668 -[_UIViewControllerTransitionContext completeTransition:] + 116 
15 UIKit        0x000000018a70b454 -[UITransitionView notifyDidCompleteTransition:] + 252 
16 UIKit        0x000000018a70af38 -[UITransitionView _didCompleteTransition:] + 1404 
17 UIKit        0x000000018a70a9a8 -[UITransitionView _transitionDidStop:finished:] + 124 
18 UIKit        0x000000018a616d3c -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 312 
19 UIKit        0x000000018a616bc4 -[UIViewAnimationState animationDidStop:finished:] + 108 
20 QuartzCore       0x0000000189dddc2c CA::Layer::run_animation_callbacks(void*) + 284 
21 libdispatch.dylib     0x000000019a3a96a8 _dispatch_client_callout + 16 
22 libdispatch.dylib     0x000000019a3aedb0 _dispatch_main_queue_callback_4CF + 1844 
23 CoreFoundation      0x00000001850001f8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12 
24 CoreFoundation      0x0000000184ffe060 __CFRunLoopRun + 1628 
25 CoreFoundation      0x0000000184f2cca0 CFRunLoopRunSpecific + 384 
26 GraphicsServices     0x000000018ff94088 GSEventRunModal + 180 
27 UIKit        0x000000018a644ffc UIApplicationMain + 204 
28 MyApp        0x0000000100093918 main (main.m:16) 
29 libdyld.dylib      0x000000019a3da8b8 <redacted> + 4 


Binary Images: 
... 

A meno che non trovo un approccio più facile questa sarà la strada da percorrere per ora per me. Potrebbe essere utile creare uno script che estrae gli stack di chiamate dal file di registro, rimuova gli spazi bianchi iniziali e li inserisca nel registro degli arresti anomali.

+0

Questo mi ha fatto davvero chiudere ma non ho mai avuto la simbolizzazione di lavorare. La mia soluzione era di prendere un vero registro di crash e sostituire il contenuto di un thread con la traccia dello stack manuale. L'esecuzione di symbolicatecrash su quel file ha funzionato – Miniroo

0

SYMBOLICATECRASH

navi di Apple uno script con XCode che accelera il processo symbolication di una relazione incidente nella sua interezza. Se hai un dSYM, il tuo binario dell'app e un rapporto di crash, questo è probabilmente il metodo di simbolizzazione più semplice. Non devi preoccuparti di nessuno degli indirizzi: questo script analizzerà l'intero file di dettagli del crash e userà ATOS per risolvere tutti gli indirizzi in simboli per te.

Individuare il “symbolicatecrash” sul sistema:

cd /Applications/Xcode.app 
find . -name symbolicatecrash 

Esportare la variabile d'ambiente DEVELOPER_DIR, se non esiste

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer" 

Copiare il binario .app, la segnalazione di crash, e il file .dSYM in una cartella temporanea (ad esempio ~/tmp). Eseguire lo script come il nostro esempio qui sotto:

/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash -v ApteligentExampleApp.crash ApteligentExampleApp.app.dSYM/ 

Se tutto va bene, lo script dovrebbe symbolicate tuo intero file e l'output incidente il risultato alla finestra del terminale.Questo script non fa nulla che non potresti fare manualmente con ATOS o un altro strumento, ma ti farà ottenere ciò che ti serve più velocemente.

Source

Problemi correlati