Как опция отладки-g изменяет двоичный исполняемый файл?


при написании кода C / C++ для отладки двоичного исполняемого файла параметр debug должен быть включен в компиляторе / компоновщике. В случае GCC опция - g. Когда опция отладки включена, как это влияет на двоичный исполняемый файл? Какие дополнительные данные хранятся в файле, который позволяет функции отладчика, как это делает?

7 58

7 ответов:

- g указывает компилятору хранить информацию о таблице символов в исполняемом файле. Среди прочего, это включает в себя:

  • символ имена
  • введите информацию для символов
  • файлы и номера строк, где символы пришли из

Отладчики используют эту информацию для вывода значимых имен символов и связывания инструкций с определенными строками в источнике.

для некоторых компиляторов, поставляя -g отключит некоторые процессы оптимизации. Например, icc задает уровень оптимизации по умолчанию-O0 с -g, Если вы явно не укажете -O[123]. Кроме того, даже если вы поставляете-O[123], оптимизации, которые предотвращают трассировку стека, все равно будут отключены (например, удаление указателей кадра из кадров стека. Это оказывает лишь незначительное влияние на производительность).

с некоторыми компиляторами,- g отключит оптимизацию, которая может запутать, откуда пришли символы (переупорядочение инструкций, развертывание цикла, встраивание и т. д.). Если вы хотите отладить с оптимизацией, вы можете использовать-g3 с gcc, чтобы обойти некоторые из них. Дополнительная отладочная информация будет включена о макросах, расширениях и функциях, которые могли быть встроены. Это может позволить отладчикам и инструментам производительности сопоставлять оптимизированный код с исходным кодом, но это лучшее усилие. Некоторые оптимизации действительно искажают код.

для получения дополнительной информации, взгляните на гном, формат отладки первоначально разработанный, чтобы идти вместе с ELF (двоичный формат для Linux и других ОС).

в дополнение к отладочной и символьной информации
Google DWARF (шутка разработчика на ELF)

по умолчанию большинство оптимизаций компилятора отключаются при включенной отладке.
Таким образом, код является чистым переводом исходного кода в машинный код, а не результатом многих узкоспециализированных преобразований, которые применяются для выпуска двоичных файлов.

но самое главное отличие (на мой взгляд)
Память в отладочных сборках обычно инициализируется для некоторых конкретных значений компилятора для облегчения отладки. В сборках выпуска память не инициализируется, если это явно не сделано кодом приложения.

проверьте документацию компилятора для получения дополнительной информации:
Но примером для DevStudio является:

  • 0xCDCDCDCD выделяется в куче, но не инициализируется
  • 0xdddddddd освободил память кучи.
  • 0xfdfdfdfd "NoMansLand" заборы автоматически размещены на границе памяти. Никогда не следует перезаписывать. Если вы перезаписываете один, вы, вероятно, уходите с конца массива.
  • 0xCCCCCCCC, выделенный в стеке, но не инициализированный

в исполняемый файл добавляется таблица символов, которая сопоставляет имена функций / переменных с местоположениями данных, чтобы отладчики могли сообщать значимую информацию, а не только указатели. Это не влияет на скорость вашей программы, и вы можете удалить таблицу символов с помощью команды "strip".

- g добавляет отладочную информацию в исполняемый файл, такую как имена переменных, имена функций и номера строк. Это позволяет отладчику, например gdb, шагать по коду строка за строкой, устанавливать точки останова и проверять значения переменных. Из-за этой дополнительной информации использование-g увеличивает размер исполняемого файла.

кроме того, gcc позволяет использовать-g вместе с-O флагами, которые включают оптимизацию. Отладка оптимизированного исполняемого файла может быть очень сложной, поскольку переменные могут быть оптимизированы, или инструкции могут быть выполнены в другом порядке. Как правило, это хорошая идея, чтобы отключить оптимизацию при использовании-g, даже если это приводит к гораздо более медленному коду.

есть некоторые совпадения с этим вопрос которая охватывает вопрос с другой стороны.

просто в качестве интереса, вы можете взломать hexeditor и взглянуть на исполняемый файл, созданный с помощью -g и один без. Вы можете увидеть символы и вещи, которые добавляются. Это может изменить сборку (-S), но я не уверен.

некоторые операционные системы (такие как z / OS) создайте "боковой файл", содержащий символы отладки. Это помогает избежать вздутия исполняемого файла с дополнительной информацией.