Каковы эффективные способы отладки оптимизированной программы C/С++?
Много раз я работаю с оптимизированным кодом (иногда даже с использованием векторизованных циклов), которые содержат ошибки и т.д. Как отладить такой код? Я ищу любые инструменты или методы. Я использую следующие (возможно устаревшие) инструменты, поэтому я хочу обновить.
Я использую следующее:
- Поскольку с ddd вы не видите код, я использую команду gdb + dissambler и вижу полученный код; Я не могу пройти через программу, используя это.
- ndisasm
Спасибо
Ответы
Ответ 1
Всегда сложнее отлаживать оптимизированные программы, но всегда есть способы. Некоторые дополнительные советы:
- Создайте сборку отладки и посмотрите, есть ли у вас ошибка в отладочной сборке. Нет смысла отлаживать оптимизированную версию, если вам это не нужно.
- Используйте valgrind, если на платформе, которая его поддерживает. Ошибки, которые вы видите, могут быть труднее понять, но часто ловить проблему часто упрощает отладку.
- Отладка printf примитивна, но иногда это самый простой способ, если у вас есть сложная проблема, которая появляется только в оптимизированных сборках.
- Если вы подозреваете проблему с синхронизацией (особенно в многопоточной программе), сверните свою собственную версию утверждения, которая прерывает или печатает, если это условие нарушено, и использовать его в нескольких выбранных местах, чтобы исключить возможные проблемы.
- Посмотрите, можете ли вы воспроизвести проблему, не используя -fomit-frame-указатели, поскольку это очень сложно отлаживать код и включать -O2 или -O3. Это может дать вам достаточно информации, чтобы найти причину вашей проблемы.
- Изолируйте части своего кода, создайте тестовый набор и посмотрите, можете ли вы идентифицировать любые тестовые теги, которые не работают. Гораздо проще отлаживать одну функцию, чем вся программа.
- Попробуйте отключить оптимизацию один за другим с параметрами -fno-X. Это может помочь вам найти общие проблемы, такие как проблемы с строгим псевдонимом.
- Включите больше предупреждений компилятора. Некоторые вещи, такие как проблемы с строгим псевдонимом, могут генерировать предупреждения компилятора, если они создают разницу в поведении между различными уровнями оптимизации.
Ответ 2
При отладке релизов вы можете ввести __asm nops; как заполнитель для точек останова (int 3). Это приятно, так как вы можете гарантировать местоположение точек останова, не запутывая оптимизацию компилятора или записывая инструкции printf/cout.
Ответ 3
Конечно, всегда легче отлаживать не оптимизированную версию. В противном случае может оказаться полезным разборка кода. Другие используемые мной технологии включают в себя частичную де-оптимизацию кода, заставляя промежуточные результаты печататься или регистрироваться, или изменяя критическую переменную на "volatile", поэтому я могу хотя бы взглянуть на это значение в отладчике.
Ответ 4
Скорее всего, вы называете оптимизированный код скремблированным, чтобы сбривать циклы (что делает сложную отладку), но на самом деле не очень оптимизировано. Вот пример того, что я имею в виду.
Я бы отключил оптимизацию, отладку и настройку компилятора, а затем включил оптимизацию компилятора, если код имеет горячие точки, которые на самом деле находятся в коде, который видит компилятор (не во внешних библиотеках). (Я определяю точку доступа как часть кода, где часто встречается ПК. Это автоматически освобождает циклы, содержащие вызовы функций, потому что они убирают ПК.)