glibc proporciona backtrace()
y backtrace_symbols()
para obtener el seguimiento de la pila de un programa en ejecución. Pero para que esto funcione, el programa debe construirse con el indicador -rdynamic
de linker.símbolos de depuración de gcc (indicador -g) vs opción -rdinámica del vinculador
¿Cuál es la diferencia entre -g
bandera pasada a gcc vs linker's -rdynamic
? Para un código de muestra que hice readelf para comparar las salidas. -rdynamic
parece producir más información en Symbol table '.dynsym'
Pero no estoy muy seguro de cuál es la información adicional.
Incluso si yo strip
un programa binario construido usando -rdynamic
, backtrace_symbols()
continúo trabajando.
Cuando strip
elimina todos los símbolos del binario ¿por qué está dejando atrás lo que haya sido agregado por la bandera -rdynamic
?
Editar: Seguimiento de preguntas basadas en la respuesta de la estera debajo ..
Por el mismo código de ejemplo que tomó esta es la diferencia que veo con -g
& -rdynamic
sin ninguna opción ..
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
hay más secciones, más entradas en .symtab
tabla pero .dynsym
sigue siendo el mismo ..
[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
no hay secciones adicionales de depuración, las entradas son .symtab 70 (igual que la invocación de vainilla gcc), pero más .dynsym
entradas ..
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
Estas son las preguntas que tengo ..
En gdb puede hacer bt para obtener la bactrace. Si eso funciona solo con
-g
, ¿por qué necesitamos-rdynamic
para que backtrace_symbols funcione?Comparando las adiciones a
.symtab
con-g
& adiciones a.dynsym
con-rdynamic
no son exactamente lo mismo .. ¿Se contempla en cualquiera de los dos mejor información de depuración en comparación con el otro? FWIW, el tamaño de la salida producida es así: con -g> con -dinámica> sin la opción¿Cuál es exactamente el uso de .dynsym? ¿Son todos los símbolos exportados por este binario? En ese caso, ¿por qué foo entrar en .dynsym porque no estamos compilando el código como una biblioteca?
Si enlace mi código usando todas las bibliotecas estáticas entonces -rdinámica no es necesario para que backtrace_symbols funcione?
Se da la circunstancia de que traza lamentablemente no utiliza símbolos de depuración [si hay] como la mayoría de otras herramientas, incluyendo el BGF, valgrind, etc. –