Что такое отладочная сборка

от admin

Отладочная сборка

Существует версия Windows, называемая отладочной сборкой (checked build), которая доступна только подписчикам MSDN Operating Systems. Это перекомпилированный исходный код Windows с выставленным флажком времени компиляции DBG (включает условный код отладки и трассировки).

Кроме того, чтобы было проще понять машинный код, не производится последующая обработка двоичных кодов Windows, оптимизирующая расположение кода для быстрого выполнения. (См. раздел «Debugging Performance-Optimized Code» вфайлесправки Debugging Tools for Windows.)

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

Эксперимент: Определение факта запуска отладочной сборки.

Чтобы вывести на экран информацию о том, какая именно сборка запущена, отладочная или поступающая в продажу (которая называется свободной), встроенного средства не существует. Но эта информация доступна через свойство «Debug» класса Win32_OperatingSystem инструментария управления WindowsManagementInstrumentation (WMI). Значение этого свойства выводится с помощью следующего примера сценария Microsoft Visual Basic:

strComputer = «.»

Set objWMIService = GetObject(«winmgmts:» _

& «!\\» & strComputer & «\root\cimv2»)

Set colOperatingSystems = objWMIService.ExecQuery _

(«SELECT * FROM Win32_OperatingSystem»)

For Each objOperatingSystem in colOperatingSystems

Wscript.Echo «Заголовок: » & objOperatingSystem.Caption

Wscript.Echo «Отладка: » & objOperatingSystem.Debug

Wscript.Echo «Версия: » & objOperatingSystem.Version

Next

Чтобы увидеть его в работе, наберите предыдущий код и сохраните его в файле.

При запуске сценария на экран будет выведена следующая информация:

Сервер сценариев Windows (Microsoft R) версия 5.8

Корпорация Майкрософт (Microsoft Corp.), 1996-2001. Все права защищены.

Заголовок: Microsoft Windows 7 Ultimate

Отладка: Ложь

Версия: 6.1.7600

Эта система запущена не из отладочной сборки, поскольку показанный здесь флажок отладки не установлен, то есть имеет значение False (Ложь).

Основная часть дополнительного кода в исполняемых файлах отладочной версии является результатом использования макроса ASSERT и (или) макроса NT_ASSERT, которые определены в заголовочном файле WDK Wdm.h и описаны в WDK-документации. Макрос проверяет условие (например, приемлемость структуры данных или параметра), и если выражение вычисляется в FALSE, макрос вызывает функцию RtlAssert, работающую в режиме ядра, которая вызывает функцию DbgPrintEx для отправки текста отладочного сообщения в предназначенный для этого сообщения буфер.

Если подключен отладчик ядра, это сообщение выводится автоматически вместе с вопросом пользователю о том, что делать в связи с сообщением об отказе (установить контрольную точку, проигнорировать, завершить процесс или завершить поток). Если система не была запущена с отладчиком ядра (с использованием параметра отладки в базе данных конфигурации загрузки — Boot Configuration Database, BCD) и отладчик ядра не подключен, неудачное выполнение теста утверждения — ASSERT приведет к ошибке проверки системы.

Перечень проверок ASSERT, проводимых некоторыми подпрограммами поддержки ядра, приводится в разделе «Checked Build ASSERTs» WDK-документации.

Отладочная сборка может также пригодиться системным администраторам своей дополнительной подробной информационной трассировкой, которая может быть включена для некоторых компонентов. (Подробныеинструкцииданывстатьебазызнаний Microsoft «HOWTO: Enable Verbose Debug Tracing in Various Drivers and Subsystems».)

Этот информационный вывод отправляется во внутренний буфер отладочных сообщений с использованием ранее упомянутой функции DbgPrintEx. Для просмотра отладочных сообщений можно либо подключить к целевой системе отладчик ядра (что требует загрузки целевой системы в отладочном режиме), воспользовавшись после этого командой !dbgprint при осуществлении отладки локального ядра, либо воспользоваться средством Dbgview.exeиз набора Sysinternals(www.microsoft.com/technet/sysinternals).

Чтобы воспользоваться отладочной версией операционной системы необязательно устанавливать всю отладочную сборку. Достаточно в обычную поставляемую установку скопировать отладочную версию образа ядра (Ntoskrnl.exe) и соответствующую HAL-библиотеку (Hal.dll).

Преимущество такого подхода заключается в том, что драйверы устройств и другие фрагменты кода ядра получают строгий контроль, присущий отладочной сборке без необходимости запуска работающих медленнее отладочных версий всех компонентов системы. Подробныеинструкцииприведенывразделе «Installing Just the Checked Operating System and HAL» WDK-документации.

И наконец, отладочная сборка может также пригодиться для тестирования кода, выполняемого в пользовательском режиме, что обусловлено только лишь разницей в синхронизации системы. (Причина в том, что в ядре проводятся дополнительные проверки и компоненты скомпилированы без оптимизации.)

Зачастую ошибки многопоточной синхронизации связаны с особыми условиями ее организации. При запуске тестов на системе, где работает отладочная сборка (или, как минимум, отладочная версия ядра и соответствующая HAL-библиотека), сам факт другой синхронизации всей системы может выявить скрытые ошибки синхронизации, которые не проявляют себя на системах их обычных комплектов поставки.

C# Debug vs Release. Сборки и дебаг

Из коробки в C# нам доступны 2 способа сборки проекта release и debug.

О компиляции C# кода

Исходный код C # проходит через 2 этапа компиляции, чтобы стать инструкциями CPU, которые могут быть выполнены.

Обычно первый этап происходит на вашем CI сервере, а второй шаг происходит позже, во время работы самого приложения. Когда же мы работаем локально в Visual Studio, то она все эти шаги выполняет перед запуском приложения из меню Debug.

Шаг первый. Компиляция приложения
Ваш код превращается в Common Intermediate Language (CIL), который уже может быть выполнен в любом окружении, которое поддерживает CIL. Обратите внимание, что собранная сборка не является читаемым текстом IL, а фактически метаданными и байтовым кодом в виде двоичных данных.

На данном шаге будет выполнена некоторая оптимизация кода (будет описано дальше).

Шаг второй. JIT компилятор
JIT компилятор конвертирует IL код в инструкции процессора, которые можно выполнить на вашей машине. Однако не вся компиляция происходит заранее — в нормальном режиме, код компилируется, только тогда когда его вызывают в первый раз, после чего он кэшируется.

Компилятор JIT — это всего лишь один из целого ряда сервисов, которые составляют Common Language Runtime (CLR), позволяя ему выполнять код .NET.

Основная часть оптимизации кода будет проведена на этом шаге.

Что такое оптимизация кода в одном предложении?

Это процесс улучшения таких факторов, как скорость выполнения, размер кода, энергопотребление, а в случае .NET — время, которое требуется для компилятора JIT — без изменения функциональности.

Почему мы заинтересованы в оптимизации в этой статье?

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

Оптимизация компилятора C#

C# компилятор на самом деле делает очень мало оптимизаций. На самом деле большенство оптимизаций производит JIT компилятор во время генерирования машинного кода. Тем не менее это все равно ухудшит работу по отладке.

Инструкция nop в IL
Команда nop имеет ряд применений при программировании на низком уровне, например, для включения небольших предсказуемых задержек или инструкции по перезаписи, которые вы хотите удалить. В IL коде данные конструкции помогают при использовании точек останова (breakpoints) для того чтобы они вели себя предсказуемо.

Если мы посмотрим на IL код, который сгенерирован с отключенными оптимизациями:

Эта инструкция мапиться с фигурной скобкой, для того чтобы мы могли поставить на нее точку остановки:

Даная инструкция была бы удалена если у нас включены оптимизации, что повлияло бы на отладку приложения.

Более подробное обсуждение оптимизаций компилятора C# в статье Эрика Липперта: Что делает переключатель оптимизации?. Существует также хороший комментарий о IL до и после оптимизации здесь.

Оптимизация JIT компилятора

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

Я рассмотрю один пример, чтобы проиллюстрировать влияние оптимизации на отладку.
Встраивание методов

Для реальной оптимизации, сделанной компилятором JIT, я буду показывать инструкции по сборке. Это всего лишь макет на C #, чтобы дать вам общую идею.

Предположим, что у меня есть:

Компилятор JIT, скорее всего, выполнит встроенное расширение. Он заменит вызов метода Add() телом данного метода:

Конфигурации сборки по умолчанию

Итак, теперь, когда мы обновили понимание компиляции .NET и двух «слоев» оптимизации, давайте взглянем на 2 конфигурации сборки, доступные «из коробки»:

Довольно просто — релиз полностью оптимизирован, отладка совсем отсутствует, что, как вы сейчас знаете, имеет фундаментальное значение для того, насколько легко отлаживать ваш код. Но это просто поверхностное представление о возможностях аргументов отладки и оптимизации.

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

Я попытался продемонстрировать данные аргументы из кода Roslyn и mscorlib. Теперь мы имеем следующие классы:

Синие элементы обозначаю аргументы командной строки, а зеленые их представление в коде.

Перечисление OptimizationLevel

OptimizationLevel.Debug отключает все оптимизации для C# и JIT компилятора с помощью DebuggableAttribute.DebuggingModes, который с помощью ildasm, мы можем видеть:

OptimizationLevel.Release включает все оптимизации (DebuggableAttribute.DebuggingModes = ( 01 00 02 00 00 00 00 00 )) что в свою очередь соответсвует DebuggingModes.IgnoreSymbolStoreSequencePoints

При этом уровне оптимизации точки останова могут быть оптимизированы. Что приведет к тому что мы не сможем их поставить и остановиться.

Типы IL

Типы IL кода описаны в классе ILEmitStyle.

На диаграмме выше показано, что тип генерируемого IL кода C# компилятором зависит от OptimizationLevel.
Аргумент debug не меняет его, за исключение аргумента debug+ когда OptimizationLevel установлен в Release.

  • ILEmitStyle.Debug — нету оптимизация IL в дополнение к добавлению nop инструкций для сопоставления точекостановки с IL.
  • LEmitStyle.Release — полная оптимизация.
  • ILEmitStyle.DebugFriendlyRelease — выполняет только те оптимизации, которые не помешаю отладке приложения.

Следующий кусок кода продемонстрирует все это наглядно.

Комментарий в исходном файле Optimizer.cs гласит, что они не опускают никаких определенных пользователем локальных переменных (примеры на 28 строчке) и не переносят значения в стек между операторами.

Я рад, что прочитал это, так как я был немного разочарован своими собственными экспериментами в ildasm с debug +, поскольку все, что я видел, это сохранение локальных переменных.

Нет намеренной «деоптимизации», например, добавления команд nop.

Разница между debug, debug:full и debug:pdbonly.

На самом деле разницы никакой нету, что подтверждает официальная документация:

Результат остается одним и тем же — pdb файл создается.
Подгланув в CSharpCommandLineParser можем убедиться в этом. И для того чтобы проверить это, мне удалось отладить код с помощью WinDbg для обох аргументов (pdbonly и full).

Они не влияют на оптимизацию кода.
Как плюсом могу отметить что документация на Github более актуальна, но она не открывает свет на специфическое поведение для debug+

А что же такое этот ваш pdb файл?
Все очень просто, данный файл содержит всю необходимую информацию для отладки DLL и EXE. Что помогает сопоставить отладчику IL код с инструкциями в оригинальном C# коде.

Что на счет debug+?

debug+ это особенный аргумент, который не может быть заменен с помощью full и pdbonly. Как многие заметили, данный аргумент соответствует debug:full — это на самом деле не совсем правда. Если мы используем аргумент optimize-, поведение будет таким же, но для optimize+ будет свое собственное уникальное поведение (DebugFriendlyRelease).

debug- или без аргументов?

Значения по умолчанию, которые установлены в CSharpCommandLineParser.cs.

а значения для debug=:

Таким образом, мы можем с уверенностью сказать, что debug- и отсутствие аргументов отладки, приводет к одному и тому же эффекту — pdb файл не будет создан.

Запрет оптимизации JIT при загрузке модуля (Suppress JIT optimizations)

Флажок в разделе «Options->Debugging->General» это опция для отладчика в Visual Studio и не повлияет на сборки, которые вы создаете.

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

Обычно этот параметр включаю для того чтобы отладить внешние библиотеки или пакеты NuGet.

Если мы хотим подключиться отладчиком Visual Studion к продакшен сборке, которая собрана в релизной конфигурации, то при наличии у нас pdb файла, мы может еще одним способом указать JIT компилятору, о том чтобы он не оптимизировал код. Для этого нужно добавить .ini файл с таким же названием как выполняемая библиотека и указать в нем:

Что такое Just My Code?

По умолчанию эта настройка уже включена (Options->Debugging→Enable Just My Code) и отладчик думает что оптимизированный код не является пользовательским. Поэтому отладчик никогда не зайдет в такой код.

Вы можете отключить данный флаг и это, теоретически, позволит вам поставить точку остановки. Но теперь вы отлаживаете код, оптимизированный как компиляторами C# так и JIT, который едва соответствуют исходному коду. В результате у вас будут такие артефакты отладки, как непредсказуемые переходы в коде и скорее все вам не получиться получить значения в локальных переменных.

Этот параметр стоит отключать в том случае, когда у вас есть pdb файл.

Взглянем ближе на DebuggableAttribute

Выше я упомянул использование ildasm для изучения манифеста сборок для изучения DebuggableAttribute. Я также написал небольшой PowerShell скрипт для получения более дружественного результата (ссылка на скачивание).

Что означает отладка сборки и выпуска сборки, различия и использование

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

какой из них я должен использовать (я имею в виду, какие условия являются подходящими для каждого). и какую сборку я на самом деле использую, знаю, если сделать простой проект C++ в Visual Studio.[если я не изменяю настройки проектов]

Я спрашиваю об этом, потому что я пытаюсь сделать GUI, используя wxwidges 2.9.4, и они дают другой случай добавления необходимого.lib. это

release ANSI static

debug ANSI static

release Unicode static

debug Unicode static

пожалуйста, поставьте подробный ответ.

4 ответа

Отладочная сборка и выпуск сборки — это просто имена. Они ничего не значат.

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

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

Что касается внешних библиотек (например, wxwidgets): все компиляторы имеют некоторые несовместимости при использовании разных опций. Таким образом, люди, которые поставляют библиотеки (кроме исходной формы), должны предоставлять несколько разных версий, в зависимости от ряда проблем:

выпуск или отладка: версия выпуска будет скомпилирована с набором более или менее стандартных параметров оптимизации (и без отладки итератора); отладочная версия без оптимизации и с отладкой итератором. Присутствует ли отладка итератора или нет — это одна вещь, которая обычно нарушает двоичную совместимость. Поставщик библиотеки должен задокументировать, какие параметры совместимы с каждой версией.

ANSI против Unicode: это, вероятно, означает узкий char против широкого wchar_t для символьных данных. Используйте тот, который когда-либо соответствует тому, что вы используете в своем приложении. (Обратите внимание, что разница между этими двумя аспектами гораздо больше, чем просто некоторые переключатели компилятора. Часто требуется радикально другой код, и корректная обработка Unicode во всех случаях далеко не тривиальна; приложение, которое действительно поддерживает Unicode, должно знать о таких вещах, как составление символов или двунаправленное письмо.)

статический или динамический: это определяет, как библиотека связана и загружена. Обычно вам нужно статическое, по крайней мере, если вы рассчитываете на развертывание приложения на других машинах, а не на том, на котором вы его разрабатываете. Но это также зависит от вопросов лицензирования: если вам нужна лицензия для каждого компьютера, на котором развернута библиотека, возможно, имеет смысл использовать динамический.

что означает отладка сборки и выпуск сборки, различие и использование [duplicate]

Я хочу знать, что означает отладка сборки и выпуска. и какая разница между ними.

который я должен использовать (я имею в виду, какие из них подходят для каждого из них). и которые, собственно, я использую, знаю, если сделать простой проект С++ в visual studio. [если я не меняю настройки проектов]

Я спрашиваю об этом, потому что я пытаюсь сделать gui с помощью wxwidges 2.9.4, и они дают разные случаи добавления требуемого .lib. это

release ANSI static

debug ANSI static

release Unicode static

debug Unicode static

просьба указать подробный ответ.

4 ответа

Сбор и сборка отладки — это просто имена. Они ничего не значат.

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

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

Что касается внешних библиотек (например, wxwidgets): все компиляторы имеют некоторые несовместимости при использовании разных опций. Поэтому люди, которые доставлять библиотеки (кроме исходной), должны предоставить несколько разные версии, в зависимости от ряда проблем:

релиз и отладка: версия выпуска будет скомпилирована с помощью набор более или менее стандартных опций оптимизации (и без итератора отладки); отладочная версия без оптимизации и с итератором отладки. Является ли отладка итератора присутствующей или нет, это одна вещь который обычно нарушает двоичную совместимость. Поставщик библиотеки должен документ, варианты которого совместимы с каждой версией.

ANSI vs Unicode: это, вероятно, означает узкий char vs wide wchar_t для символьных данных. Использование, которое когда-либо соответствует тому, что вы используете в ваше приложение. (Заметим, что разница между этими двумя больше, чем просто некоторые компиляторы. Вы часто нуждаетесь в радикальном другой код и правильная обработка Юникода во всех случаях далека от тривиальным; приложение, которое действительно поддерживает Unicode, должно знать такие вещи, как составление символов или двунаправленное письмо.)

static vs. dynamic: это определяет, как связана библиотека и загружен. Обычно вам понадобится статический, по крайней мере, если вы рассчитываете на развертывание ваше приложение на других машинах, чем тот, на котором вы его разрабатываете. Но это также зависит от вопросов лицензирования: если вам нужна лицензия для каждого машина, в которой развернута библиотека, может иметь смысл использовать динамический.

Читать:
Для чего используют аккумуляторы 18650

Похожие публикации