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

в чем разница между Начать Отладку (Ф5) и запуск без отладки ( CTRL-Ф5) когда код компилируется в режим выпуска?

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

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

4 ответов


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

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

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


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

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

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

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

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

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

при запуске с отладкой вещи работают по-разному по нескольким причинам:

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

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

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


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