Практическое руководство. Отладка оптимизированного кода
Примечание |
---|
Отображаемые диалоговые окна и команды меню могут отличаться от описанных в справке в зависимости от текущих настроек или выпуска.Для изменения настроек выберите Параметры импорта и экспорта в меню Сервис.Дополнительные сведения см. в разделе Параметры Visual Studio. |
Когда компилятор оптимизирует код, он перераспределяет и реорганизует инструкции.Это приводит к повышению эффективности скомпилированного кода.В связи с этим перераспределением отладчик не всегда может идентифицировать исходный код, соответствующий набору инструкций.
Оптимизация может повлиять на:
Локальные переменные (могут быть удалены оптимизатором или перемещены в места, недоступные для отладки).
Код внутри функций (изменяется расположение при слиянии оптимизатором блоков кода).
Имена функций в фреймах стека вызовов (могут оказаться некорректными при слиянии оптимизатором двух функций).
Фреймы в стеке вызовов почти всегда верные, но при условии наличия символов для всех фреймов.Фреймы в стеке вызовов могут оказаться некорректными при повреждении стека, при наличии функций на ассемблере, или в фреймах операционной системы при отсутствии соответствующих символов в стеке вызовов.
Глобальные и статические переменные всегда отображаются правильно.Это же относится к структурным типам.Если существует указатель на структуру и его значение правильно, каждая переменная-элемент структуры имеет правильное значение.
В связи с этими ограничениями следует по возможности отлаживать неоптимизированные версии программы.По умолчанию оптимизация выключена в конфигурации отладки программы Visual C++ и включается в конфигурации выпуска.
Тем не менее, ошибка может появиться только в оптимизированной версии программы.В этом случае отлаживать нужно как раз оптимизированный код.
Включение оптимизации в конфигурации построения отладки
При создании нового проекта выберите в качестве конечного продукта Win32 Debug.Используйте целевой объект Win32Debug до тех пор, пока программа не полностью отлаживанна и можно создать целевой объект Win32 Release.Компилятор не оптимизирует Win32 Debug.
Выберите проект в обозревателе решений.
В меню Вид выберите команду Страницы свойств.
В диалоговом окне Страницы свойств убедитесь, что в раскрывающемся списке Конфигурация выбран пункт Debug.
В окне папок слева выберите папку C/C++.
В папке C++ выберите пункт Optimization.
В списке свойств справа найдите Optimization.Параметр этого свойства скорее всего будет Disabled (/Od).Выберите один из других параметров (Minimum Size(/O1), Maximum Speed(/O2), Full Optimization(/Ox) или Custom).
Если для свойства Customвыбран параметр Optimization, это означает, что можно устанавливать параметры для любого из остальных свойств, показанных в списке.
При отладке оптимизированного кода перейдите в окно Дизассемблирование, чтобы просмотреть, какие инструкции в действительности создаются и выполняются.При задании точек останова следует знать, что они могут двигаться вместе с инструкцией.Рассмотрим следующий пример кода:
for (x=0; x<10; x++)
Допустим, точка останова установлена на этой строке.Можно ожидать, что точка останова будет пройдена 10 раз. Но если код оптимизирован, она будет пройдена всего один раз.Это связано с тем, что первая инструкция задает для x значение 0.Компилятор распознает, что конкретная инструкция должна быть выполнена один раз, и убирает ее из цикла.Точка останова перемещается вместе с ней.Инструкции, которые сравнивают и увеличивают x, остаются внутри цикла.При просмотре окна Дизассемблирование для лучшего контроля размер шага автоматически равен одной инструкции, что бывает полезно при пошаговом прохождении оптимизированного кода.