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





-g указывает компилятору хранить информацию таблицы символов в исполняемом файле. Среди прочего, сюда входят:
Отладчики используют эту информацию для вывода значимых имен символов и для связывания инструкций с определенными строками в источнике.
Для некоторых компиляторов указание -g отключит определенные оптимизации. Например, icc устанавливает уровень оптимизации по умолчанию на -O0 с помощью -g, если вы явно не указали -O [123]. Кроме того, даже если вы укажете -O [123], оптимизации, предотвращающие трассировку стека, все равно будут отключены (например, удаление указателей фреймов из фреймов стека. Это лишь незначительно влияет на производительность).
В некоторых компиляторах -g отключит оптимизацию, которая может запутать происхождение символов (переупорядочение инструкций, развертывание цикла, встраивание и т. д.). Если вы хотите отладить с оптимизацией, вы можете использовать -g3 с gcc, чтобы обойти некоторые из этих проблем. Будет добавлена дополнительная отладочная информация о макросах, расширениях и функциях, которые могли быть встроены. Это может позволить отладчикам и средствам повышения производительности сопоставлять оптимизированный код с исходным исходным кодом, но это лучшее усилие. Некоторые оптимизации действительно искажают код.
Для получения дополнительной информации взгляните на DWARF, формат отладки, изначально разработанный для использования с ELF (двоичный формат для Linux и других ОС).
Если флаг -g в компиляторе Sun не отключает некоторые оптимизации, отладочная информация НЕ должна замедлять ваш код.
Это код OpenMP, и он действительно замедлял его. Я играл с фракталами и работал над расширениями компилятора OpenMP. Код в одном потоке работал медленнее, чем код без OpenMP в одном потоке. Отключил отладку и скорость выровняла.
Отметил. Это действительно интересно. Может быть, он добавляет туда лишний материал, чтобы сообщить отладчику о параллельных регионах ... Здесь говорится (docs.sun.com/source/819-3683/OpenMP.html), что вы можете получить отображение основного потока обратно в источник, но не на подчиненные устройства, что тоже кажется странным.
Я думаю, что это так, конечно, не влияет на GCC, конечно, меня удивило, когда однопоточный код изменился с 11 секунд до 22.: / При отключенной отладке и 4 потоках (у меня Q6600) он упал примерно до 3 секунд .
gcc4 на самом деле поддерживает OpenMP, поэтому, возможно, вы столкнетесь с подобными проблемами. Я слышал, что выступление не так уж и хорошо для начала.
Просто из любопытства, предоставили ли вы дополнительные параметры оптимизации при компиляции с помощью -g (например, -g -O3) или вы просто добавили -g без явного указания -O [123]? Первый может сбросить вас до -O0, по крайней мере, на icc.
У меня была настройка проекта на максимальную оптимизацию (с отладкой), SSE, MMX и т. д., Когда я вернусь домой, я опубликую точные параметры, возможно, я что-то пропустил.
Хорошо, используя - #, чтобы указать, что -fast расширяется до: cc -xopenmp -fast - # Расширяется до: -D__MATHERR_ERRNO_DONTCARE -fns -nofstore -fsimple = 2 -fsingle -xalias_level = basic -xarch = ssse3 -xbuiltin =% all -xcache = 32/64/8: 4096/64/16 -xchip = core2 -xdepend -xlibmil -xlibmopt -xO5 -xopenmp -xregs = frameptr
Флаг -g также включен, комментарии просто не дают мне места для публикации полной строки. :) Версия отладки: в реальном времени: 6.060 с, время пользователя: 22.815 с, версия выпуска: 3.774 с, время пользователя: 13.902 с (оба используют 4 потока)
К исполняемому файлу добавляется таблица символов, которая сопоставляет имена функций / переменных с местоположениями данных, чтобы отладчики могли сообщать значимую информацию, а не только указатели. Это не влияет на скорость вашей программы, и вы можете удалить таблицу символов с помощью команды 'strip'.
Есть некоторое совпадение с этим вопрос, которое покрывает проблему с другой стороны.
Просто ради интереса, вы можете взломать hexeditor и взглянуть на исполняемый файл, созданный с -g, а другой - без него. Вы можете видеть символы и то, что добавлено. Может поменять и сборку (-S), но я не уверен.
-g добавляет отладочную информацию в исполняемый файл, такую как имена переменных, имена функций и номера строк. Это позволяет отладчику, такому как gdb, проходить код построчно, устанавливать точки останова и проверять значения переменных. Из-за этой дополнительной информации использование -g увеличивает размер исполняемого файла.
Кроме того, gcc позволяет использовать -g вместе с флагами -O, которые включают оптимизацию. Отладка оптимизированного исполняемого файла может быть очень сложной, потому что переменные могут быть оптимизированы, а инструкции могут выполняться в другом порядке. Как правило, рекомендуется отключать оптимизацию при использовании -g, даже если это приводит к гораздо более медленному коду.
В дополнение к отладочной и символьной информации
Google DWARF (шутка разработчиков об ELF)
По умолчанию большинство оптимизаций компилятора отключены, когда включена отладка. Таким образом, код - это чистый перевод исходного кода в машинный код, а не результат многих узкоспециализированных преобразований, которые применяются для выпуска двоичных файлов.
Но самое главное отличие (на мой взгляд)
Память в сборках отладки обычно инициализируется некоторыми значениями, специфичными для компилятора, для облегчения отладки. В сборках релиза память не инициализируется, если это явно не сделано кодом приложения.
Дополнительную информацию см. В документации к компилятору:
Но пример для DevStudio:
- 0xCDCDCDCD Allocated in heap, but not initialized
- 0xDDDDDDDD Released heap memory.
- 0xFDFDFDFD "NoMansLand" fences automatically placed at boundary of heap memory. Should never be overwritten. If you do overwrite one, you're probably walking off the end of an array.
- 0xCCCCCCCC Allocated on stack, but not initialized
Некоторые операционные системы (например, z / OS) создают «побочный файл», содержащий символы отладки. Это помогает не перегружать исполняемый файл дополнительной информацией.
Чтобы добавить к этому, это также может замедлить исполняемый файл. Я тестировал некоторый код OpenMP с компилятором Sun Studio, и с отладочной информацией код работал намного медленнее. Просто нужно иметь в виду.