Su Mac OS X è stato deciso che il linker (ld
) non elabora tutte le informazioni di debug quando si collega il programma. Le informazioni di debug sono spesso 10 volte la dimensione dell'eseguibile del programma, in modo che il linker elabori tutte le informazioni di debug e includa nel binario eseguibile un grave danno ai tempi di collegamento. Per lo sviluppo iterativo - compilazione, collegamento, compilazione, collegamento, debug, compilazione di link - questo è stato un vero successo.
Invece il compilatore genera le informazioni di debug di DWARF nei file .s, l'assemblatore le pubblica nei file .o e il linker include una "mappa di debug" nel binario eseguibile che indica agli utenti di informazioni di debug dove tutto il i simboli sono stati trasferiti durante il collegamento.
Un consumatore (fare il debug .o file) carica la mappa di debug dall'eseguibile ed elabora tutto il nano nei file .o quando necessario, rimappare i simboli secondo le istruzioni della mappa di debug.
dsymutil
può essere pensato come un linker di informazioni di debug. Fa lo stesso processo: legge la mappa di debug, carica il file DWG dai file .o, riposiziona tutti gli indirizzi e quindi genera un singolo binario di tutti i DWARF ai loro indirizzi finali collegati. Questo è il pacchetto dSYM.
Una volta che hai un bundle dSYM, hai un semplice vecchio standard DWARF che può essere elaborato da qualsiasi strumento di lettura nano (che può gestire file binari di Mach-O).
C'è un ulteriore raffinamento che fa funzionare tutto questo, gli UUID inclusi nei binari di Mach-O. Ogni volta che il linker crea un binario, emette un UUID a 128 bit nel comando di caricamento LC_UUID (v. otool -hlv
o dwarfdump --uuid
). Identifica in modo univoco quel file binario. Quando dsymutil
crea il dSYM, include quell'UUID. I debugger associeranno solo un dSYM e un eseguibile se hanno UUID corrispondenti - nessun timestamp mod dodgy file o qualcosa del genere.
Possiamo anche utilizzare gli UUID per individuare i dSYM per i binari. Vengono visualizzati nei rapporti sugli arresti anomali, includiamo un importatore Spotlight che puoi utilizzare per cercarli, ad es. mdfind "com_apple_xcode_dsym_uuids == E21A4165-29D5-35DC-D08D-368476F85EE1"
se il dSYM si trova in una posizione indicizzata Spotlight. Puoi anche avere un repository di dSYM per la tua azienda e un programma che può recuperare il dSYM corretto dato un UUID - forse un po 'di database mysql o qualcosa del genere - così si esegue il debugger su un eseguibile casuale e si ha istantaneamente tutto il debug informazioni per quell'eseguibile. Ci sono alcune cose carine che puoi fare con gli UUID.
Ma comunque, per rispondere alla tua domanda origine: Il binario unstripped ha la mappa di debug, i file .o hanno il nano, e quando viene eseguito dsymutil
questi sono combinati per creare il fascio dSYM.
Se si desidera visualizzare le voci della mappa di debug, fare nm -pa executable
e sono tutte lì. Sono nella forma dei vecchi record di pugnalate: il linker sapeva già come elaborare i pugni, quindi era più facile usarli, ma vedrai come funziona senza troppi problemi, magari riferirsi ad una documentazione di pugnalata se sei incerta.
In che modo 'dsymutil' sa dove sono i file .o? Non vedo alcuna opzione nella manpage per dirlo. Inoltre ho bisogno di compilare il file binario '-g3', e in tal caso, posso spogliarlo dopo che ho' dsymutil''d? Grazie. – mxcl
Ci sono voci "mappa di debug" nell'eseguibile prima che vengano eliminate con i nomi file dei file .o. 'nm -pa binario | grep OSO' li elencherà. Sono nella forma del vecchio formato di debug di stab (perché il linker sapeva già come gestire quel formato). Dopo aver creato il tuo dSYM, puoi eliminarli dal file eseguibile. Non dovresti aver bisogno di usare '-g3' sulla piattaforma Mac,' -g' dovrebbe essere sufficiente. Penso che '-g3' restituisca le informazioni macro di pre-elaborazione, ma Lldb non le legge su Mac OS X (e non so se clang ne possa persino produrre output.) –
Grazie per questa risposta dettagliata e utile. – mxcl