Lors de l'écriture de code C/C++, afin de déboguer l'exécutable binaire, l'option de débogage doit être activée sur le compilateur/éditeur de liens. Dans le cas de GCC, l'option est -g. Lorsque l'option de débogage est activée, comment affecte-t-il l'exécutable binaire? Quelles données supplémentaires sont stockées dans le fichier qui autorise la fonction de débogage comme elle le fait?
-g indique au compilateur de stocker les informations de la table des symboles dans l'exécutable. Cela comprend entre autres:
Les débogueurs utilisent ces informations pour générer des noms significatifs pour les symboles et pour associer des instructions à des lignes particulières de la source.
Pour certains compilateurs, fournir -g désactivera certaines optimisations. Par exemple, icc définit le niveau d'optimisation par défaut sur -O0 avec -g sauf si vous indiquez explicitement -O [123]. De plus, même si vous fournissez -O [123], les optimisations qui empêchent le traçage de pile seront toujours désactivées (par exemple, supprimer les pointeurs de trame des trames de pile. Cela n'a qu'un effet mineur sur les performances).
Avec certains compilateurs, -g désactivera les optimisations qui peuvent confondre la provenance des symboles (réorganisation des instructions, déroulement de boucle, alignement, etc.). Si vous souhaitez déboguer avec l'optimisation, vous pouvez utiliser -g3 avec gcc pour contourner cela. Des informations de débogage supplémentaires seront incluses sur les macros, les extensions et les fonctions qui peuvent avoir été intégrées. Cela peut permettre aux débogueurs et aux outils de performance de mapper du code optimisé à la source d'origine, mais c'est le meilleur effort. Certaines optimisations modifient vraiment le code.
Pour plus d'informations, jetez un œil à NAIN , le format de débogage conçu à l'origine pour aller avec ELF (le format binaire pour Linux et d'autres systèmes d'exploitation).
Une table de symboles est ajoutée à l'exécutable qui mappe les noms de fonction/variable aux emplacements de données, de sorte que les débogueurs puissent renvoyer des informations significatives, plutôt que de simples pointeurs. Cela n'affecte pas la vitesse de votre programme et vous pouvez supprimer la table des symboles avec la commande 'strip'.
En plus des informations de débogage et de symbole
Google DWARF (Une blague de développeur sur ELF)
Par défaut, la plupart des optimisations du compilateur sont désactivées lorsque le débogage est activé.
Le code est donc la pure traduction de la source en code machine plutôt que le résultat de nombreuses transformations hautement spécialisées appliquées aux versions binaires.
Mais la différence la plus importante (à mon avis)
La mémoire dans les versions de débogage est généralement initialisée à certaines valeurs spécifiques au compilateur pour faciliter le débogage. Dans les versions, la mémoire n'est pas initialisée sauf si cela est explicitement fait par le code de l'application.
Consultez la documentation de votre compilateur pour plus d'informations:
Mais un exemple pour DevStudio est:
- 0xCDCDCDCD Alloué en tas, mais non initialisé
- 0xDDDDDDDD Mémoire de tas libérée.
- 0xFDFDFDFD Clôtures "NoMansLand" placées automatiquement à la limite de la mémoire du tas. Ne doit jamais être écrasé. Si vous en écrasez un, vous quittez probablement l'extrémité d'un tableau.
- 0xCCCCCCCC Alloué sur la pile, mais non initialisé
-g ajoute des informations de débogage dans l'exécutable, telles que les noms des variables, les noms des fonctions et les numéros de ligne. Cela permet à un débogueur, tel que gdb, de parcourir le code ligne par ligne, de définir des points d'arrêt et d'inspecter les valeurs des variables. En raison de ces informations supplémentaires, l'utilisation de -g augmente la taille de l'exécutable.
De plus, gcc permet d'utiliser -g avec les drapeaux -O, qui activent l'optimisation. Le débogage d'un exécutable optimisé peut être très délicat, car les variables peuvent être optimisées, ou les instructions peuvent être exécutées dans un ordre différent. En règle générale, il est judicieux de désactiver l'optimisation lors de l'utilisation de -g, même si cela entraîne un code beaucoup plus lent.
Il y a un certain chevauchement avec cela question qui couvre le problème de l'autre côté.
Juste comme une question d'intérêt, vous pouvez ouvrir un hexeditor et jeter un oeil à un exécutable produit avec -g
et un sans. Vous pouvez voir les symboles et les éléments ajoutés. Cela peut changer l'Assemblée (-S
) aussi, mais je ne suis pas sûr.
Certains systèmes d'exploitation (comme z/OS ) produisent un "fichier latéral" qui contient les symboles de débogage. Cela permet d'éviter de gonfler l'exécutable avec des informations supplémentaires.