¿Cómo funciona la opción de depuración -g Cambiar el ejecutable binario?

Al escribir código C / C ++, para depurar el ejecutable binario, la opción de depuración debe estar habilitada en el comstackdor / enlazador. En el caso de GCC, la opción es -g. Cuando la opción de depuración está habilitada, ¿cómo afecta el ejecutable binario? ¿Qué datos adicionales se almacenan en el archivo que permiten la función de depuración como lo hace?

-g le dice al comstackdor que almacene la información de la tabla de símbolos en el ejecutable. Entre otras cosas, esto incluye:

  • nombres de símbolo
  • escriba información para símbolos
  • archivos y números de línea de donde provienen los símbolos

Los depuradores usan esta información para generar nombres significativos para símbolos y asociar instrucciones con líneas particulares en la fuente.

Para algunos comstackdores, el suministro de -g deshabilitará ciertas optimizaciones. Por ejemplo, icc establece el nivel de optimización predeterminado en -O0 con -g a menos que indique explícitamente -O [123]. Además, incluso si suministras -O [123], las optimizaciones que evitan el seguimiento de la stack seguirán desactivadas (por ejemplo, eliminando los punteros de los marcos de la stack, lo que tiene un efecto menor en el rendimiento).

Con algunos comstackdores, -g deshabilitará las optimizaciones que pueden confundir el origen de los símbolos (reordenamiento de instrucciones, desenrollado de bucles, alineación, etc.). Si desea depurar con optimización, puede usar -g3 con gcc para evitar algo de esto. Se incluirá información adicional de depuración sobre macros, expansiones y funciones que pueden haber sido inlineadas. Esto puede permitir que los depuradores y las herramientas de rendimiento asocien el código optimizado a la fuente original, pero es el mejor esfuerzo. Algunas optimizaciones realmente destruyen el código.

Para obtener más información, eche un vistazo a DWARF , el formato de depuración diseñado originalmente para ir junto con ELF (el formato binario para Linux y otros sistemas operativos).

Además de la información de depuración y símbolos
Google DWARF (una broma de desarrollador en ELF)

De forma predeterminada, la mayoría de las optimizaciones del comstackdor se desactivan cuando la depuración está habilitada.
Por lo tanto, el código es la traducción pura de la fuente en Código máquina en lugar del resultado de muchas transformaciones altamente especializadas que se aplican a los archivos binarios de la versión.

Pero la diferencia más importante (en mi opinión)
La memoria en las comstackciones de depuración generalmente se inicializa en algunos valores específicos del comstackdor para facilitar la depuración. En las comstackciones de versiones, la memoria no se inicializa, a menos que lo haga explícitamente el código de la aplicación.

Verifique la documentación de su comstackdor para más información:
Pero un ejemplo para DevStudio es:

  • 0xCDCDCDCD Asignado en el montón, pero no inicializado
  • 0xDDDDDDDD Liberación de la memoria del montón.
  • 0xFDFDFDFD Las vallas “NoMansLand” se colocan automáticamente en el límite de la memoria del montón. Nunca debe ser sobrescrito. Si sobrescribe uno, probablemente esté caminando al final de una matriz.
  • 0xCCCCCCCC Asignado en la stack, pero no inicializado

Se agrega una tabla de símbolos al ejecutable que correlaciona los nombres de funciones / variables con las ubicaciones de los datos, de modo que los depuradores puedan informar información significativa, en lugar de solo punteros. Esto no afecta la velocidad de su progtwig, y ​​puede eliminar la tabla de símbolos con el comando ‘strip’.

-g agrega información de depuración en el archivo ejecutable, como los nombres de las variables, los nombres de las funciones y los números de línea. Esto permite que un depurador, como gdb, recorra el código línea por línea, establezca puntos de interrupción e inspeccione los valores de las variables. Debido a esta información adicional, el uso de -g aumenta el tamaño del ejecutable.

Además, gcc permite usar -g junto con -O flags, que activan la optimización. La depuración de un archivo ejecutable optimizado puede ser muy complicado, ya que las variables pueden optimizarse o las instrucciones se pueden ejecutar en un orden diferente. En general, es una buena idea desactivar la optimización cuando se usa -g, aunque se obtenga un código mucho más lento.

Hay cierta superposición con esta pregunta que cubre el problema desde el otro lado.

Solo como cuestión de interés, puedes abrir un editor hexadecimal y echar un vistazo a un ejecutable producido con -g y uno sin él. Puedes ver los símbolos y cosas que se agregan. También puede cambiar el ensamblaje ( -S ), pero no estoy seguro.

Algunos sistemas operativos (como z / OS ) producen un “archivo lateral” que contiene los símbolos de depuración. Esto ayuda a evitar la hinchazón del ejecutable con información adicional.