glibc fornisce backtrace()
e backtrace_symbols()
per ottenere la traccia dello stack di un programma in esecuzione. Ma per farlo funzionare il programma deve essere costruito con il flag -rdynamic
del linker.simboli di debug di gcc (-g flag) rispetto all'opzione -dynamic del linker
Qual è la differenza tra il flag -g
passato a gcc vs linker -rdynamic
flag? Per un codice di esempio mi sono deciso a confrontare le uscite. -rdynamic
sembra produrre più informazioni sotto Symbol table '.dynsym'
Ma non sono abbastanza sicuro di quali siano le informazioni aggiuntive.
Anche se I strip
un file binario del programma creato utilizzando -rdynamic
, backtrace_symbols()
continua a funzionare.
Quando strip
rimuove tutti i simboli dal binario perché lascia dietro a ciò che è stato aggiunto dal flag -rdynamic
?
Edit: Follow-up domande basate sulla risposta di Mat seguente ..
Per lo stesso codice di esempio si ha questa è la differenza che vedo con -g
& -rdynamic
senza alcuna opzione ..
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 218 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
Symbol table '.symtab' contains 70 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400200 0 SECTION LOCAL DEFAULT 1
2: 000000000040021c 0 SECTION LOCAL DEFAULT 2
con -g
ci sono più sezioni, più voci in .symtab
tabella ma .dynsym
rimane lo stesso ..
[26] .debug_aranges PROGBITS 0000000000000000 0000095c
0000000000000030 0000000000000000 0 0 1
[27] .debug_pubnames PROGBITS 0000000000000000 0000098c
0000000000000023 0000000000000000 0 0 1
[28] .debug_info PROGBITS 0000000000000000 000009af
00000000000000a9 0000000000000000 0 0 1
[29] .debug_abbrev PROGBITS 0000000000000000 00000a58
0000000000000047 0000000000000000 0 0 1
[30] .debug_line PROGBITS 0000000000000000 00000a9f
0000000000000038 0000000000000000 0 0 1
[31] .debug_frame PROGBITS 0000000000000000 00000ad8
0000000000000058 0000000000000000 0 0 8
[32] .debug_loc PROGBITS 0000000000000000 00000b30
0000000000000098 0000000000000000 0 0 1
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 218 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
Symbol table '.symtab' contains 77 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400200 0 SECTION LOCAL DEFAULT 1
con -rdynamic
senza sezioni supplementari di debug, le voci .symtab sono 70 (lo stesso di vaniglia gcc invocazione), ma più .dynsym
voci ..
Symbol table '.dynsym' contains 19 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 218 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2)
2: 00000000005008e8 0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
3: 0000000000400750 57 FUNC GLOBAL DEFAULT 12 __libc_csu_fini
4: 00000000004005e0 0 FUNC GLOBAL DEFAULT 10 _init
5: 0000000000400620 0 FUNC GLOBAL DEFAULT 12 _start
6: 00000000004006f0 86 FUNC GLOBAL DEFAULT 12 __libc_csu_init
7: 0000000000500ab8 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
8: 00000000004006de 16 FUNC GLOBAL DEFAULT 12 main
9: 0000000000500aa0 0 NOTYPE WEAK DEFAULT 23 data_start
10: 00000000004007c8 0 FUNC GLOBAL DEFAULT 13 _fini
11: 00000000004006d8 6 FUNC GLOBAL DEFAULT 12 foo
12: 0000000000500ab8 0 NOTYPE GLOBAL DEFAULT ABS _edata
13: 0000000000500a80 0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
14: 0000000000500ac0 0 NOTYPE GLOBAL DEFAULT ABS _end
15: 00000000004007d8 4 OBJECT GLOBAL DEFAULT 14 _IO_stdin_used
16: 0000000000500aa0 0 NOTYPE GLOBAL DEFAULT 23 __data_start
17: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
18: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
Symbol table '.symtab' contains 70 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400200 0 SECTION LOCAL DEFAULT 1
2: 000000000040021c 0 SECTION LOCAL DEFAULT 2
Ora queste sono le domande che ho ..
In gdb si può fare bt per ottenere il bactrace. Se funziona con solo
-g
, perché abbiamo bisogno di-rdynamic
per il funzionamento di backtrace_symbols?Confrontando le aggiunte alla
.symtab
con-g
& aggiunte.dynsym
con-rdynamic
non sono esattamente la stessa cosa .. Ha uno dei due forniscono una migliore informazioni di debug rispetto agli altri? FWIW, la dimensione dell'output prodotto è la seguente: con -g> con -rdynamic> con nessuna opzioneChe cosa è esattamente l'uso di .dynsym? Sono tutti i simboli esportati da questo binario? In tal caso, perché è inutile andare in .dynsym perché non stiamo compilando il codice come una libreria.
Se collego il mio codice utilizzando tutte le librerie statiche, per il backtrace_symbols non è necessario il funzionamento dinamico?
Accade così che backtrace purtroppo non fa uso di simboli di debug [se disponibile] come la maggior parte di altri strumenti, tra cui gdb, valgrind, ecc –