gcc symboles de débogage (-g drapeau) vs linker -rdynamic option
glibc fournit backtrace()
et backtrace_symbols()
pour obtenir la trace de la pile d'exécution d'un programme. Mais pour que cela fonctionne, le programme doit être construit avec linker -rdynamic
drapeau.
Quelle est la différence entre -g
drapeau passé à gcc vs linker -rdynamic
drapeau ? Pour un exemple de code je n'ai readelf de comparer les résultats. -rdynamic
semble produire plus d'infos sous Symbol table '.dynsym'
Mais je ne suis pas tout à fait sûr de ce que les informations supplémentaires est.
Même si je strip
un programme binaire construit à l'aide de -rdynamic
, backtrace_symbols()
continuer à travailler.
Quand strip
supprime tous les symboles de la binaire pourquoi est-il en laissant derrière tout ce qui a été ajouté par le -rdynamic
drapeau ?
Edit: Suivi des questions basées sur des Tapis de réponse ci-dessous..
Pour le même exemple de code que vous avez pris c'est la différence que je vois avec -g
& -rdynamic
sans aucune option..
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 __libc_start_main@GLIBC_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
avec -g
il y a plus d'articles, plus d'entrées dans .symtab
table, mais .dynsym
reste le même..
[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 __libc_start_main@GLIBC_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
avec -rdynamic
pas de supplémentaires de débogage sections .symtab entrées sont 70 (de même que la vanille gcc invocation), mais plus .dynsym
entrées..
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 __libc_start_main@GLIBC_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
Maintenant ce sont les questions que j'ai..
-
Dans gdb, vous pouvez faire bt pour obtenir le bactrace. Si cela fonctionne avec juste
-g
pourquoi avons-nous besoin-rdynamic
pour backtrace_symbols de travail ? -
Comparant les ajouts à
.symtab
avec-g
& ajouts à.dynsym
avec-rdynamic
ils ne sont pas exactement les mêmes.. Ne soit un fournir de meilleures informations de débogage par rapport à l'autre ?
FWIW, la taille de la sortie produite est comme ceci: avec -g > avec -rdynamic > avec ni l'option -
Ce qui est exactement l'utilisation de l' .dynsym ? Est-ce que tous les symboles exportés par ce binaire ? Dans ce cas, pourquoi est toto va en .dynsym parce que nous ne sommes pas de la compilation le code comme une bibliothèque.
-
Si j'ai un lien sur mon code à l'aide de toutes les bibliothèques statiques puis -rdynamic n'est pas nécessaire pour backtrace_symbols de travail ?
- Il se trouve que la trace n'est malheureusement pas à utiliser les symboles de débogage [si disponible] comme la plupart des autres outils, y compris gdb, valgrind, etc.
Vous devez vous connecter pour publier un commentaire.
Selon les docs:
Ceux qui ne sont pas des symboles de débogage, ils sont l'éditeur de liens dynamiques des symboles. Ceux qui ne sont pas supprimés par
strip
car il serait (dans la plupart des cas) saut de l'exécutable - ils sont utilisés par le moteur d'exécution de l'éditeur de liens pour faire le lien final étape de votre exécutable.Exemple:
Compiler et lier sans
-rdynamic
(et pas des optimisations, évidemment)Si l'exécutable a un
.symtab
avec tout. Mais remarquez que.dynsym
ne mentionne pasfoo
à tous - il a l'essentiel là-dedans. Ce n'est pas de suffisamment d'informations pourbacktrace_symbols
de travail. Il s'appuie sur les informations présentes dans cette section pour faire correspondre les adresses de code avec les noms de fonction.Maintenant compiler avec
-rdynamic
:Même chose pour les symboles dans
.symtab
, mais maintenantfoo
a un symbole dans un symbole dynamique de la section (et un tas d'autres symboles apparaissent il y a maintenant trop). Cela rendbacktrace_symbols
travail - il a désormais suffisamment d'informations (dans la plupart des cas) à la carte des adresses de code avec les noms de fonction.Bande:
Maintenant
.symtab
est parti, mais la dynamique de la table des symboles est toujours là, et l'exécutable s'exécute. Doncbacktrace_symbols
fonctionne toujours trop.Bande de la dynamique de la table des symboles:
... et vous obtenez une fracture de l'exécutable.
Une lecture intéressante pour ce
.symtab
et.dynsym
sont utilisés, c'est ici: À l'intérieur de l'ELFE Tables de symboles. L'une des choses à noter est que.symtab
n'est pas nécessaire au moment de l'exécution, de sorte qu'il est rejeté par le chargeur. Cette section ne reste pas dans l'espace mémoire du processus..dynsym
, d'autre part, la est nécessaires lors de l'exécution, de sorte qu'il est conservé dans le processus de l'image. De sorte qu'il est disponible pour des choses commebacktrace_symbols
de recueillir des informations sur le processus en cours à partir de l'intérieur de lui-même.Donc en bref:
strip
parce que ce serait rendre le fichier exécutable non-chargeablesbacktrace_symbols
besoins des symboles dynamiques de comprendre ce qui appartient le code de la fonction quebacktrace_symbols
ne pas utiliser les symboles de débogageD'où le comportement vous l'avez remarqué.
Pour vos questions spécifiques:
gdb
est un débogueur. Il utilise les informations de débogage dans le fichier exécutable et les bibliothèques pour afficher les informations pertinentes. Il est beaucoup plus complexe quebacktrace_symbols
, et inspecte les fichiers sur votre disque dur en plus du live processus.backtrace_symbols
ne le fait pas, il est tout à fait dans le processus de sorte qu'il ne peut pas accéder à des sections qui ne sont pas chargés dans le fichier exécutable de l'image. Debug sections ne sont pas chargé dans l'exécution de l'image, de sorte qu'il ne peut pas les utiliser..dynsym
n'est pas une section débogage. C'est une section utilisée par l'éditeur de liens dynamique..symbtab
n'est pas un débogage section, soit, mais il peut être utilisé par débogueur qui ont accès à l'exécutable (bibliothèque) des fichiers.-rdynamic
ne pas générer de débogage sections, seulement que l'étendue dynamique de la table des symboles. L'exécutable de la croissance de-rdynamic
dépend entièrement du nombre de symboles dans ce fichier exécutable (et l'alignement/rembourrage considérations). Il devrait être beaucoup moins que-g
.printf
et certains de démarrage de l'application des procédures de la bibliothèque C. Ces signes extérieurs doit être indiqué quelque part dans le fichier exécutable: c'est ce que.dynsym
est utilisé pour, et c'est pourquoi le fichier exe a une.dynsym
même si vous ne spécifiez pas-rdynamic
. Lorsque vous ne spécifiez, le linker ajoute d'autres symboles qui ne sont pas nécessaires pour le processus de travail, mais peut être utilisé par des choses commebacktrace_symbols
.backtrace_symbols
ne va pas résoudre les noms de fonction si vous lier statiquement. Même si vous spécifiez-rdynamic
, le.dynsym
section ne sera pas émis dans l'exécutable. Pas de tables de symboles est chargé dans le fichier exécutable de l'image, de sortebacktrace_symbols
ne peut pas mapper code adresses de symboles..symtab
n'est pas chargé dans le processus de l'image. Il n'est pas disponible pourbacktrace_symbols
à utiliser._gmon_start
définie sur 0 x 0? Ce qui se passe quand laPLT
pousse l'entrée pour_gmon_start
sur la pile et les appels de l'éditeur de liens dynamique? Il semble que l'exécutable n'ont aucun moyen de savoir où_gmon_start
est.