Comment l’option de débogage -g modifie-t-il l’exécutable binary?

Lors de l’écriture de code C / C ++, pour déboguer l’exécutable binary, 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 binary? Quelles sont les données supplémentaires stockées dans le fichier qui autorisent la fonction de débogage?

-g indique au compilateur de stocker les informations de la table des symboles dans l’exécutable. Entre autres choses, cela comprend:

  • noms de symboles
  • taper info pour les symboles
  • fichiers et numéros de ligne d’où proviennent les symboles

Les débogueurs utilisent ces informations pour générer des noms significatifs pour les symboles et pour associer des instructions à des lignes spécifiques dans 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 la stack seront toujours désactivées (par exemple, en supprimant les pointeurs de trame des frameworks de stack. Cela n’a qu’un effet mineur sur les performances).

Avec certains compilateurs, -g désactivera les optimisations qui peuvent induire en erreur d’où proviennent les symboles (réordonnancement des instructions, déroulement de la boucle, incrustation, etc.). Si vous voulez déboguer avec l’optimisation, vous pouvez utiliser -g3 avec gcc pour contourner certains problèmes. Des informations supplémentaires de débogage seront incluses sur les macros, les extensions et les fonctions qui peuvent avoir été insérées. Cela peut permettre aux débogueurs et aux outils de performance de mapper le code optimisé à la source d’origine, mais c’est le meilleur effort. Certaines optimisations modifient vraiment le code.

Pour plus d’informations, consultez DWARF , le format de débogage conçu à l’origine pour accompagner ELF (le format binary pour Linux et les autres systèmes d’exploitation).

En plus des informations de débogage et des symboles
Google DWARF (Une blague de développeur sur ELF)

Par défaut, la plupart des optimisations de compilateur sont désactivées lorsque le débogage est activé.
Le code est donc la traduction pure de la source en code machine plutôt que le résultat de nombreuses transformations hautement spécialisées appliquées aux versions binarys.

Mais la différence la plus importante (à mon avis)
La mémoire dans les versions Debug est généralement initialisée à des valeurs spécifiques au compilateur pour faciliter le débogage. Dans la version build, la mémoire n’est pas initialisée à moins que cela ne soit 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 “NoMansLand” clôtures placées automatiquement à la limite de la mémoire de tas. Ne devrait jamais être écrasé. Si vous en écrasez un, vous sortez probablement de la fin d’un tableau.
  • 0xCCCCCCCC Alloué sur la stack, mais non initialisé

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 rapporter 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 ‘ssortingp’.

-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 cette information supplémentaire utilisant -g augmente la taille de l’exécutable.

De plus, gcc permet d’utiliser -g avec -O flags, ce qui active l’optimisation. Déboguer un exécutable optimisé peut être très compliqué, car les variables peuvent être optimisées ou les instructions peuvent être exécutées dans un ordre différent. En général, il est conseillé de désactiver l’optimisation lors de l’utilisation de -g, même si le code est beaucoup plus lent.

Il y a un certain chevauchement avec cette question qui couvre le problème de l’autre côté.

Juste à titre d’intérêt, vous pouvez ouvrir un éditeur hexadécimal et regarder un exécutable produit avec -g et un sans. Vous pouvez voir les symboles et les objects ajoutés. Cela peut aussi changer l’assemblage ( -S ), mais je ne suis pas sûr.

Certains systèmes d’exploitation (tels que z / OS ) produisent un “fichier secondaire” contenant les symboles de débogage. Cela permet d’éviter de gonfler l’exécutable avec des informations supplémentaires.