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
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
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
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