2012-04-20 11 views
9

ho ricevuto una segnalazione di crash via AirBrake.io che non è symbolicated. Dal momento che il rapporto sugli arresti anomali non è esattamente nello stesso formato di un crash del registro Apple, non posso semplicemente rilasciarlo su XCode come al solito, quindi ho preso la stessa build dal mio archivio XCode cercando di simbolizzarlo sulla riga di comando. Con il seguente risultato:Atos e dwarfdump non symbolicate mio indirizzo

$ atos -o kidsapp.app/kidsapp 0x0002fc4c 
0x0002fc4c (in kidsapp) 

Sono assolutamente sicuro che sto usando la stessa corporatura come il rapporto di incidente è da. Così ho anche provato con dwarfdump:

$ dwarfdump --lookup 0x0002fc4c --arch armv7 kidsapp.app.dSYM 
---------------------------------------------------------------------- 
File: kidsapp.app.dSYM/Contents/Resources/DWARF/kidsapp (armv7) 
---------------------------------------------------------------------- 
Looking up address: 0x000000000002fc4c in .debug_info... not found. 
Looking up address: 0x000000000002fc4c in .debug_frame... not found. 

Nessun risultato. C'è qualcos'altro oltre all'utilizzo del file dSYM sbagliato che potrei fare male? So che è quella corretta poiché questa è la versione indicata nel rapporto di arresto anomalo in AirBrake e si trova nel mio archivio XCode.

Tutte le idee/suggerimenti sono benvenuti!

risposta

9

Prima di tutto controllare se il dSYM è davvero quello corretto per tale applicazione:

dwarfdump --uuid kidsapp.app/kidsapp 
dwarfdump --uuid kidsapp.app.dSYM 

Entrambi dovrebbero restituire lo stesso risultato.

controllo successivo se il dSYM ha alcun contenuto valido

dwarfdump --all kidsapp.app.dSYM 

Questo dovrebbe dare almeno alcune informazioni, diverso not found.

immagino che il dSYM è danneggiato. In generale, è possibile che si desideri utilizzare un reporter di arresto anomalo che fornisce un rapporto di arresto anomalo completo con tutti i thread e le ultime informazioni di backtrace dell'eccezione. Consiglio di utilizzare qualcosa basato su PLCrashReporter, ad es. QuincyKit (Open Source SDK + Server + symbolication sul tuo mac) o HockeyApp (Open Source SDK + Servizio a pagamento + simbolizzazione lato server) (Nota: sono uno degli sviluppatori entrambi!)

+0

Sto avendo lo stesso problema. Ho segnalato un arresto anomalo che fornisce la traccia dello stack ma nessuno dei simboli del mio progetto che finiscono nello stack può essere trovato nel mio dSYM dell'archivio. Gli UUID corrispondono ma i simboli sono tutti disattivati. Com'è possibile e come posso risolvere questo? Apple modifica il binario in qualche modo prima di rilasciarlo nell'app store, compromettendo così l'allineamento con il mio dSYM? – NSProgrammer

+0

Dovrai prendere in considerazione la diapositiva del binario e l'indirizzo iniziale dell'app. Non puoi semplicemente usare l'indirizzo di memoria dalla traccia dello stack. Basta usare lo script symbolicatecrash di Xcode che fa tutto ciò di cui hai bisogno. – Kerni

+0

Ma se tutto quello che ho sono i simboli (dovrei aver detto stack dump, non trace) che mi fornisce puramente valori esadecimali come faccio a tener conto della "slide"? – NSProgrammer

22

Ho usato la seguente aritmetica per capire fuori:

slide + stack address - load address = symbol address

e

stack address è il valore esadecimale che ricevo da mia relazione crash dump di stack (non è un file .crash, solo il dump dello stack).

e

slide è la vmaddr dei cmd LC_SEGMENT durante l'esecuzione otool -arch armv7 -l APP_BINARY_PATH. Il mio solitamente finisce con 0x00001000.

e

load address è la parte complicata. In realtà è la differenza tra l'indirizzo dello stack più basso del thread principale e il primo indirizzo della parte del mio file binario che contiene i simboli quando si esegue dwarfdump --arch armv7 --all DSYM_BINARY_PATH. Questo è semplicemente l'indirizzo simbolico della funzione main. Quindi se il tuo indirizzo di crash più basso è 0x8000 e l'indirizzo simbolico della tua funzione principale è 0x2000 allora il tuo load address è 0x6000.

Ora con TUTTI questi pezzi, posso calcolare l'indirizzo del simbolo e inserirlo in atos o dwarfdump: dwarfdump --lookup SYM_ADDR --arch armv7 APP_BINARY_PATH.

Esempio di discarica (si può vedere che il load address era 0x00003af4):

----------------------------------------------------------------------

File: /Users/user/Desktop/MyApp.xcarchive/dSYMs/MyApp.app.dSYM/Contents/Resources/NANO/MyApp (ARMv7)

----------------------------------------------------------------------

0x00000024: [0x00003af4 - 0x00003b4e) principale

012.351.

0x00000098: [0x00003b50 - 0x00003d8c) - [Applicazione MyAppDelegate: didFinishLaunchingWithOptions:]

... il resto della discarica

La parte più difficile è stata rendersi conto che una delle 2 librerie statiche I' d inclusi i loro simboli sono stati rimossi prima di essere collegati al binario della mia app! Ciò ha lasciato un enorme divario di indirizzi simbolici, quindi mi sono ritrovato solo con i due terzi dei simboli che mi servivano nel mio dSYM.

essere sicuri di avere i seguenti flag impostati su NO nel progetto librerie Xcode statico in modo che quando si collega contro di esso, si può tirare nei simboli per la vostra applicazione binario (che può essere successivamente spogliata): COPY_PHASE_STRIP, DEAD_CODE_STRIPPING, e STRIP_INSTALLED_PRODUCT.

Ora si può chiedere, "cosa devo fare se il dump dello stack non include la funzione principale poiché non è sul thread principale in modo che non possa ottenere l'indirizzo di stack della funzione principale?". A ciò risponderei: "Non ho una vaga idea!". Incrocia le dita e spera di poter ottenere una traccia dello stack che includa l'indirizzo del simbolo o utilizzare un sistema di segnalazione degli arresti anomali che riproduca i registri degli arresti anomali di Apple, come PLCrashReporter.

[EDIT 26 Maggio 2013] -

E 'stato portato alla mia attenzione che il load address è davvero l'indirizzo del mach-o binario. Anche se quello che ho descritto sopra può spesso funzionare - non è in realtà corretto. Questo può essere ottenuto tramite il CRASH REPORT, tuttavia il punto di questa risposta è stato quello di fornire i simboli di un arresto anomalo quando non si dispone di un rapporto di arresto anomalo. Il modo migliore che ho imparato a capire lo load address quando voglio simbolizzare è assicurarmi di registrare lo load address con lo.

Ho creato personalmente un sistema per la registrazione degli arresti anomali (non i rapporti sugli arresti anomali) e il loro invio a un bucket S3 in cui posso recuperarli in seguito per il debug. Quando avvio la mia applicazione, memorizzo nella cache loe lo e lo main function address per l'uso se la mia app si arresta in modo anomalo e invio uno.

NOTA: le funzioni dyld utilizzano #include <mach-o/dyld.h>

slide = L'indirizzo restituito da _dyld_get_image_vmaddr_slide(0)

load address = l'indirizzo restituito da _dyld_get_image_header(0)

main function address = l'ultimo indirizzo in [NSThread callStackReturnAddresses] quando invitato la principale thread

In caso di incidente I'm sur e per accedere [NSThread callStackReturnAddresses] e [NSThread callStackSymbols] così come l'architettura che può essere recuperare avendo questo metodo:

- (NSString*) arch 
{ 
    NSString* arch = 
#ifdef _ARM_ARCH_7 
     @"armv7"; 
#elif defined (_ARM_ARCH_6) 
     @"armv6"; 
#else 
     nil; 
#endif 

    return arch; 
} 

io non so ancora come differenziare tra i ARMv7 e armv7s però.

Quindi questo può essere d'aiuto in futuro. Ho in programma di prendere tutto ciò che ho imparato e trasformarlo in un semplice strumento di crash, meglio dello strumento natos (probabilmente natos v2).

Ho aggiornato Natos per sostenere la fornitura di load address manualmente: https://github.com/NSProgrammer/natos

+3

Ho creato uno strumento da riga di comando per fare tutto il duro lavoro. Semplicemente è necessario 1) il percorso xcarchive, 2) il simbolo dell'indirizzo stack della funzione principale, 3) l'indirizzo stack del simbolo desiderato, 4) l'architettura di interesse. Si trova su github: https://github.com/nob1984/natos – NSProgrammer

+0

Nice writeup, ma purtroppo c'è un grosso errore in questo: l'indirizzo di caricamento è ** NON ** quello che hai scritto. L'indirizzo di caricamento può essere trovato nella sezione immagini binarie del rapporto di arresto anomalo ed è l'indirizzo iniziale dell'intervallo di indirizzi del corrispondente binario. – Kerni

+0

Ho usato i tuoi strumenti, ma come posso ottenere _mainFunctionStackAddress? Trovo un indirizzo di dwarfdump sul mio file dsym e l'ho usato, ma il risultato che mi ha dato è stato lo stesso con gli atos spiegati, non riesco ancora a trovare la giusta posizione del punto di crash. – Zhou

0

penso che questo post può aiutare, https://stackoverflow.com/a/12559150/1773317. Il commit di Joe ha risolto il mio problema.

Il motivo è che i miei file .app e .dSYM non possono essere indicizzati da riflettori, quindi il mio XCode non può simboleggiare correttamente le informazioni sugli arresti anomali.

2

Per chi che certe volte non ha il valore di indirizzo di carico in questo modo:

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 

ho creato un semplice bash per aiutarmi a eseguire il debug:

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

E 'appena legge il percorso per l'app, il nome dell'app, l'indirizzo di runtime e il valore dopo il segnale "+" (il valore decimale) e quindi trovare il valore per l'indirizzo di caricamento per eseguire il comando atos.

Problemi correlati