Практическое руководство. Отладка оптимизированного кода
Этот раздел применим к:
Выпуск |
Visual Basic |
C# |
F# |
C++ |
Web Developer |
---|---|---|---|---|---|
Express |
Только машинные коды |
||||
Pro, Premium и Ultimate |
Только машинные коды |
Примечание
Отображаемые диалоговые окна и команды меню могут отличаться от описанных в справке в зависимости от текущих настроек или выпуска.Для изменения настроек выберите Параметры импорта и экспорта в меню Сервис.Дополнительные сведения см. в разделе Работа с параметрами.
Когда компилятор оптимизирует код, он перераспределяет и реорганизует инструкции. Это приводит к повышению эффективности скомпилированного кода. В связи с этим перераспределением отладчик не всегда может идентифицировать исходный код, соответствующий набору инструкций.
Оптимизация может повлиять на:
Локальные переменные (могут быть удалены оптимизатором или перемещены в места, недоступные для отладки).
Код внутри функций (изменяется расположение при слиянии оптимизатором блоков кода).
Имена функций в фреймах стека вызовов (могут оказаться некорректными при слиянии оптимизатором двух функций).
Фреймы в стеке вызовов почти всегда верные, но при условии наличия символов для всех фреймов. Фреймы в стеке вызовов могут оказаться некорректными при повреждении стека, при наличии функций на ассемблере, или в фреймах операционной системы при отсутствии соответствующих символов в стеке вызовов.
Глобальные и статические переменные всегда отображаются правильно. Это же относится к структурным типам. Если существует указатель на структуру и его значение правильно, каждая переменная-элемент структуры имеет правильное значение.
В связи с этими ограничениями следует по возможности отлаживать неоптимизированные версии программы. По умолчанию оптимизация выключена в конфигурации отладки программы 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, остаются внутри цикла. При просмотре окна Дизассемблирование для лучшего контроля размер шага автоматически равен одной инструкции, что бывает полезно при пошаговом прохождении оптимизированного кода.