Visual С++: разница между запуском и без отладки в режиме деблокирования

В чем разница между Начать отладку (F5) и Начать без отладки (CTRL - F5), когда код скомпилирован в Режим выпуска?

Я вижу, что CTRL - F5 в 10 раз быстрее, чем F5 для некоторого кода на С++. Если я не ошибаюсь, отладчик присоединяется к процессу выполнения для F5, и это не для CTRL - F5. Поскольку это режим выпуска, скомпилированный код не содержит отладочной информации. Итак, если у меня нет точек останова, время выполнения должно быть одинаковым для двух, не так ли?!

(Предположим, что режимы Release и Debug являются типичными конфигурациями, которые вы получаете при создании нового проекта Visual С++.)

Ответы

Ответ 1

Проблема в том, что Windows бросает специальную кучу Debug, если она обнаруживает, что ваша программа работает под отладчиком. Это, похоже, происходит на уровне ОС и не зависит от настроек режима Debug/Release для вашей компиляции.

Вы можете обойти эту "функцию", установив переменную среды: _NO_DEBUG_HEAP = 1

Эта же проблема на какое-то время меня заводила; сегодня я нашел следующее, откуда получен этот пост: http://blogs.msdn.com/b/larryosterman/archive/2008/09/03/anatomy-of-a-heisenbug.aspx

Ответ 2

"Начать без отладки" просто говорит Windows запускать приложение, как оно обычно запускалось.

"Начать с отладки" запускает отладчик VS и запускает приложение в отладчике.

Это действительно не имеет особого отношения к настройкам сборки отладки/выпуска.

Когда вы создаете конфигурацию вашего отладки по умолчанию, вы будете иметь следующие основные отличия от сборки релиза:

  • Исправленный код не будет оптимизирован, поэтому его легче отлаживать, поскольку он более точно соответствует вашему источнику.
  • Компилятор и компоновщик выдаст файл .PDB, содержащий много дополнительной информации, чтобы помочь отладчику - наличие или отсутствие этой информации не имеет никакого значения для производительности кода, простота отладки.
  • Условные макросы, такие как ASSERT и VERIFY, будут не-операциями в сборке релизов, но активны в сборке отладки.

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

Когда вы запускаете "с отладкой", все происходит по-разному по нескольким причинам:

  • Отладчик VS очень неэффективен при запуске, отчасти потому, что все в VS медленнее - до версий VS2010 каждый пиксель экрана будет перекрашен примерно в 30 раз по мере того, как IDE пошатнется в режиме отладки с большим количеством мигания и мерцания.
  • В зависимости от того, как настроены настройки, отладчик может потратить много времени при запуске, пытаясь загрузить символы (например, файлы PDB) для множества и многих компонентов ОС, которые являются частью вашего процесса, - он может попробовать получить эти файлы за Интернет, который может принести возраст в некоторых обстоятельствах.
  • Все действия, которые обычно выполняет ваше приложение (загрузка DLL, запуск потоков, обработка исключений), вызывают предупреждение об отладчике. Это влияет как на замедление их, так и на то, чтобы заставить их работать последовательно.

Ответ 3

IsDebuggerPresent() и OutputDebugString() ведут себя по-другому в зависимости от того, подключен ли отладчик.

IsDebuggerPresent() просто возвращает другое значение, поэтому ваша программа может реагировать на это значение и вести себя по-разному специально. OutputDebugString() возвращается намного быстрее, если отладчик не подключен, поэтому, если он много раз вызывался, вы увидите, что программа работает намного быстрее без отладчика.

Ответ 4

При запуске "с отладкой" используется куча отладки, даже для режима выпуска. Это приводит к серьезным замедлениям в коде с использованием большого количества malloc/free или new/delete, что может произойти в коде С++, если вы его не заметите, потому что библиотеки/классы имеют тенденцию скрывать от вас данные управления памятью.