Поделиться через


отладку оптимизированного кода

Примечание.

В зависимости от установок или выпуска сервера доступные диалоговые окна и команды меню могут отличаться от описанных в справке. Чтобы изменить параметры, выберите Импорт и экспорт параметров в меню Сервис . Дополнительные сведения см. в разделе "Сброс всех параметров".

Примечание.

Параметр компилятора /Zo (улучшение оптимизированной отладки) (представленный в Visual Studio Update 3) создает более подробные сведения об отладке оптимизированного кода (проекты, которые не созданы с параметром компилятора /Od ). Дополнительные сведения см. в разделе Параметры /O (оптимизация кода). Это обеспечивает улучшенную поддержку отладки локальных переменных и встроенных функций.

Изменение и продолжение отключено при использовании параметра компилятора /Zo .

Когда компилятор оптимизирует код, он перераспределяет и реорганизует инструкции. Это приводит к повышению эффективности скомпилированного кода. В связи с этим перераспределением отладчик не всегда может идентифицировать исходный код, соответствующий набору инструкций.

Оптимизация может повлиять на:

  • Локальные переменные (могут быть удалены оптимизатором или перемещены в места, недоступные для отладки).

  • Код внутри функций (изменяется расположение при слиянии оптимизатором блоков кода).

  • Имена функций в фреймах стека вызовов (могут оказаться некорректными при слиянии оптимизатором двух функций).

    Фреймы в стеке вызовов почти всегда верные, но при условии наличия символов для всех фреймов. Фреймы в стеке вызовов могут оказаться некорректными при повреждении стека, при наличии функций на ассемблере, или в фреймах операционной системы при отсутствии соответствующих символов в стеке вызовов.

    Глобальные и статические переменные всегда отображаются правильно. Это же относится к структурным типам. Если существует указатель на структуру и его значение правильно, каждая переменная-элемент структуры имеет правильное значение.

    В связи с этими ограничениями следует по возможности отлаживать неоптимизированные версии программы. По умолчанию оптимизация отключена в конфигурации отладки программы C++ и включена в конфигурации выпуска.

    Тем не менее, ошибка может появиться только в оптимизированной версии программы. В этом случае отлаживать нужно как раз оптимизированный код.

Включение оптимизации в конфигурации построения отладки

  1. При создании нового проекта выберите в качестве конечного продукта Win32 Debug. Используйте Win32 Debug, пока программа не будет полностью отлажена и готова к созданию сборки Win32 Release. Компилятор не оптимизирует Win32 Debug.

  2. Выберите проект в обозревателе решений.

  3. В меню Вид выберите пункт Страницы свойств.

  4. В диалоговом окне Страницы свойств убедитесь, что в раскрывающемся списке DebugКонфигурация выбран пункт .

  5. В окне папок слева выберите папку C/C++.

  6. В папке C++ выберите элемент Optimization.

  7. В списке свойств справа найдите Optimization. Параметр этого свойства скорее всего будет Disabled (/Od). Выберите один из параметров (Minimum Size``(/O1), Maximum Speed``(/O2), Full Optimization``(/Ox) или Custom).

  8. Если для свойства Custom выбран параметр Optimization, это означает, что можно устанавливать параметры для любого из остальных свойств, показанных в списке.

  9. Выберите "Свойства конфигурации", "C/C++", узел "Командная строка" страницы свойств проекта и добавьте (/Zo) в текстовое поле Дополнительные параметры.

    Предупреждение

    Добавление параметра /Zo приведет к отключению режима Изменить и продолжить.

    При отладке оптимизированного кода перейдите в окно Дизассемблированный код, чтобы просмотреть, какие инструкции в действительности создаются и выполняются. При задании точек останова следует знать, что они могут двигаться вместе с инструкцией. Рассмотрим следующий пример кода:

for (x=0; x<10; x++)

Допустим, точка останова установлена на этой строке. Можно ожидать, что точка останова будет пройдена 10 раз. Но если код оптимизирован, она будет пройдена всего один раз. Это связано с тем, что первая инструкция задает для x значение 0. Компилятор распознает, что конкретная инструкция должна быть выполнена один раз, и убирает ее из цикла. Точка останова перемещается вместе с ней. Инструкции, которые сравнивают и увеличивают x, остаются внутри цикла. При просмотре окна Дизассемблированный код для лучшего контроля размер шага автоматически равен одной инструкции, что бывает полезно при пошаговом прохождении оптимизированного кода.