Практическое руководство. Отладка оптимизированного кода
Обновлен: Ноябрь 2007
Этот раздел применим для следующих версий.
Выпуск |
Visual Basic |
C# |
C++ |
Web Developer |
---|---|---|---|---|
Экспресс-выпуск |
Только машинные коды |
|||
Standard |
Только машинные коды |
|||
Pro и Team |
Только машинные коды |
Условные обозначения:
Применимо |
|
Неприменимо |
|
Команда или команды по умолчанию скрыты. |
Примечание. |
---|
Отображаемые диалоговые окна и команды меню могут отличаться от описанных в справке в зависимости от активных параметров или версии. Для изменения настроек выберите Параметры импорта и экспорта в меню Сервис. Дополнительные сведения см. в разделе Параметры 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, остаются внутри цикла. При просмотре окна дизассемблированияразмер шага автоматически становится (для лучшего контроля) равным одной инструкции, что бывает полезно при отладке оптимизированного кода.