Версия Debug включает отладочную информацию, поэтому она намного больше, чем версия Release (может быть от сотен K до нескольких M). Что касается того, нужна ли вам поддержка DLL, это в основном зависит от используемых вами параметров компиляции. Если он основан на ATL, версии Debug и Release имеют аналогичные требования к DLL. Если в качестве параметра компилятора используется динамическая библиотека MFC, требуется поддержка библиотеки, например MFC42D.DLL, а для версии Release требуется поддержка MFC42.DLL.
Release не выполняет отладку исходного кода и не учитывает диагностические макросы MFC. Он использует библиотеку MFC Release для оптимизации скорости работы приложения во время компиляции. Отладка — это как раз наоборот. Он позволяет отлаживать исходный код и может определять и использовать MFC. Диагностический макрос использует библиотеку отладки MFC, которая не оптимизирована для скорости.
Focus :: Focus :: Focus :: Отладка (разработчик) Release (заказчик)
Отладка и выпуск, на мой взгляд, в основном различаются в зависимости от разных целей. Отладка обычно называется отладочной версией. Благодаря ряду параметров компиляции результат компиляции обычно содержит отладочную информацию без какой-либо оптимизации, чтобы предоставить разработчикам мощные возможности отладки приложений.
Отладочная плата Atmega 328.. Blink..
Выпуск обычно называется выпускной версией, и он предназначен для пользователей. Как правило, клиентам не разрешается отлаживать выпускную версию. Поэтому отладочная информация не сохраняется, и в то же время часто проводятся различные оптимизации для достижения наименьшего размера кода и максимальной скорости. Обеспечьте удобство для пользователей.
_DEBUG и NDEBUG
Это самый важный параметр. Эти два определения препроцессора компилятора.По умолчанию _DEBUG используется для версии Debug, а NDEBUG используется для версии Release. Возможно, они важны и не могут быть добавлены. Поскольку утверждение серии assert действует только в _DEBUG!
Следующее извлечено из файла assert.h: Код C ++
1 #ifdef NDEBUG 2 #define assert(_Expression) ((void)0) 3 #else /* NDEBUG */ 4 #ifdef __cplusplus 5 extern «C» < 6 #endif /* __cplusplus */ 7 _CRTIMP void __cdecl _wassert(__in_z const wchar_t * _Message, __in_z const wchar_t *_File, __in unsigned _Line); 8 #ifdef __cplusplus 9 >10 #endif /* __cplusplus */ 11 #define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) ) 12 #endif /* NDEBUG */
Видно, что когда _DEBUG не определен, assert становится пустым оператором и не выполняется.
Другими словами, все наши текущие выпущенные версии не могут использовать механизм утверждения для отладки программы.
- переменная.
Всем известно, что debug и release выполняют разные операции при инициализации переменных. Debug присваивает каждому байтовому биту значение 0xcc, в то время как назначение release приблизительно случайное. Если на переменную в вашей программе ссылаются без инициализации, вероятно возникнет исключение: использование в качестве управляющей переменной приведет к несогласованной ориентации процесса; использование в качестве индекса массива приведет к сбою программы; с большей вероятностью вызовет другие переменные Неточность вызывает другие ошибки. Так что это самый простой и эффективный способ инициализировать переменную значением по умолчанию сразу после ее объявления, иначе вам будет негде искать ее, когда проект большой. Ошибки кода можно игнорировать в режиме отладки, не заметив. В режиме отладки большинство массивов находятся за пределами границ, и нет ошибок, которые раскрываются в версии, которую труднее найти. - Параметры сообщения настраиваемого сообщения.
MFC предоставляет нам очень хороший механизм сообщений и добавляет собственные сообщения. Мне не нужно говорить о преимуществах. У этого тоже есть проблема отладки и выпуска? Ответ положительный. В объявлении тела функции пользовательского сообщения вы часто видите такой способ записи: afx_msg LRESULT OnMessageOwn (); Как правило, в Debug нет проблем, но когда вы находитесь в Release и используете передачу сообщений между несколькими потоками или процессами Это вызовет такие ошибки, как недопустимые дескрипторы. Непосредственной причиной этой ошибки является то, что параметр тела сообщения не добавляется, то есть его следует записать как: afx_msg LRESULT OnMessageOwn (WPARAM wparam, LPARAM lparam); 3. В режиме выпуска ошибок не возникает, но в режиме отладки сообщается об ошибке.
В данном случае это в основном вызвано неправильным написанием кода. Проверяя исходный код MFC, вы можете найти множество операторов ASSERT (утверждений). Этот макрос действителен только в режиме отладки, затем Понятно, что релизная версия не сообщает об ошибке, потому что она игнорирует ошибку, а не ее отсутствие. Это может иметь большую скрытую опасность, потому что он находится в режиме отладки, который удобнее отлаживать, и хорошо проверять свой собственный код, поэтому я не буду говорить больше. - ASSERT, VERIFY, TRACE… Макрос отладки
Эту ситуацию легко объяснить. Например: введите ASSERT в VC, а затем выберите и нажмите F12, чтобы перейти к месту определения макроса. Здесь вы можете обнаружить, что ASSERT в Debug требует выполнения AfxAssertFailedLine, а определение макроса в Release — «#define ASSERT (f) (( недействительно) 0) «. Поэтому будьте осторожны и не используйте связанные с программой переменные, такие как операторы операции записи i ++ в этих операциях макроса отладки.
VERIFY — это исключение, «#define VERIFY (f) ((void) (f))» означает выполнение.
STM32 — программирование для начинающих. Пошагово. CubeMX CubeIDE
При каких обстоятельствах версия Release выйдет из строя?
1. Библиотека времени выполнения: какая библиотека времени выполнения для связывания обычно влияет только на производительность программы. Отладочная версия библиотеки времени выполнения содержит отладочную информацию и использует некоторые механизмы защиты для поиска ошибок, поэтому производительность не так хороша, как у окончательной версии. Библиотека времени выполнения, предоставляемая компилятором, обычно очень стабильна и не вызывает ошибок версии выпуска; это потому, что библиотека времени выполнения отладки усилила обнаружение ошибок, таких как выделение памяти кучи, а иногда и ошибок отладки, но выпуск нормальный. Следует отметить, что если есть ошибка в отладке, даже если выпуск нормальный, в программе должна быть ошибка, но может случиться так, что определенный запуск версии выпуска не обнаружился.
2. Оптимизация: это основная причина ошибки, потому что исходная программа в основном напрямую транслируется, когда оптимизация выключена, и компилятор сделает ряд предположений, когда оптимизация включена. В основном бывают следующие типы ошибок:
(1) Указатель кадра опущен (сокращенно FPO): во время вызова функции вся информация о вызове (адрес возврата, параметры) и автоматические переменные помещаются в стек. . Если объявление и реализация функции различаются (параметры, возвращаемые значения, методы вызова), произойдет ошибка, но в режиме отладки доступ к стеку осуществляется через адрес, сохраненный в регистре EBP. Если нет такой ошибки, как выход массива за границы (или Вне пределов «немного»), функция обычно может выполняться нормально; в режиме Release оптимизация будет опускать указатель базового адреса стека EBP, поэтому доступ к стеку через глобальный указатель вызовет ошибку адреса возврата и сбой программы. Функция строгой типизации C ++ обнаруживает большинство этих ошибок, но если вы используете принуждение, это не сработает. Вы можете принудительно добавить параметр / Oy- compile в версию Release, чтобы отключить пропуск указателя кадра, чтобы определить, является ли этот тип ошибкой. К таким ошибкам обычно относятся:
Неправильное написание функции ответа на сообщение MFC. Правильный должен быть
afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam);
Макрос ON_MESSAGE содержит принудительное преобразование типа. Один из способов предотвратить эту ошибку — переопределить макрос ON_MESSAGE и добавить следующий код в stdafx.h (после #include «afxwin.h»), компиляция сообщит об ошибке, если прототип функции неверен.
13 #undef ON_MESSAGE 14 #define ON_MESSAGE(message, memberFxn) 15 < message, 0, 0, 0, AfxSig_lwl, 16 (AFX_PMSG)(AFX_PMSGW)(static_cast< LRESULT (AFX_MSG_CALL 17 CWnd::*)(WPARAM, LPARAM) >(,
(2) Неустойчивая переменная: Volatile сообщает компилятору, что переменная может быть изменена неизвестным образом вне программы (например, системой, другими процессами и потоками).
Чтобы повысить производительность программы, оптимизированная программа часто помещает некоторые переменные в регистр (аналогично ключевому слову register), в то время как другие процессы могут изменять только память, в которой находится переменная, а значение в регистре остается неизменным. Если ваша программа многопоточная или вы обнаружите, что значение переменной не соответствует ожидаемому, и вы уверены, что оно установлено правильно, вы, вероятно, столкнетесь с этой проблемой. Этот вид ошибки иногда проявляется как ошибка при самой быстрой оптимизации, тогда как минимальная оптимизация является нормальной. Попробуйте добавить volatile к переменным, которые вы считаете подозрительными.
(3) Оптимизация переменных: программа оптимизации оптимизирует переменные в соответствии с их использованием. Например, в функции есть неиспользуемая переменная. В отладочной версии она может закрывать массив за пределами границ. В версии Release эта переменная может быть оптимизирована. В этом случае массив за пределами границ уничтожит полезные данные в стеке.
Конечно, на самом деле ситуация намного сложнее. Связанные с этим ошибки:
незаконный доступ, включая выход за пределы массива, ошибку указателя и т. д. Например
18 void fn(void) 19 < 20 int i; 21 i = 1; 22 int a[4]; 23 < 24 int j; 25 j = 1; 26 >27 a [-1] = 1; // Конечно ошибка будет не такой очевидной, например, индекс — это переменная 28 a[4] = 1; 29 >
Хотя j вышел за пределы диапазона, когда массив находится вне диапазона, его пространство не было восстановлено, поэтому i и j покроют вне диапазона. Версия Release может быть оптимизирована, потому что i и j не очень полезны, что приводит к разрушению стека.
3 _DEBUG и NDEBUG: Когда _DEBUG определен, функция assert () будет скомпилирована, но NDEBUG не будет компилироваться. Кроме того, в VC ++ есть ряд макросов утверждений. Это включает в себя:
ANSI C assertion void assert (int выражение);
Утверждение библиотеки времени выполнения C _ASSERT (booleanExpression);
_ASSERTE( booleanExpression );
MFC assertion ASSERT (booleanExpression);
VERIFY( booleanExpression );
ASSERT_VALID( pObject );
ASSERT_KINDOF( classname, pobject );
Утверждение ATL ATLASSERT (booleanExpression);
Кроме того, компиляция макроса TRACE () также контролируется _DEBUG.
Все эти утверждения компилируются только в версии Debug и игнорируются в версии Release. Единственное исключение — VERIFY (). Фактически, эти макросы вызывают функцию assert (), но добавляют отладочный код, связанный с библиотекой.
Если вы добавите к этим макросам какой-либо программный код, а не только логические выражения (например, назначения, вызовы функций, которые могут изменять значения переменных и т. Д.), Версия Release не будет выполнять эти операции, что приведет к ошибкам. Новичкам легко сделать такие ошибки, и метод поиска также очень прост, потому что эти макросы были перечислены выше, просто используйте функцию поиска в файлах VC ++, чтобы найти места, где эти макросы используются во всех файлах проекта, и проверить их один за другим. Можно. Кроме того, некоторые эксперты могут добавить #ifdef _DEBUG и другую условную компиляцию, поэтому обратите внимание.
Кстати, стоит упомянуть макрос VERIFY (), который позволяет поместить программный код в логическое выражение. Этот макрос обычно используется для проверки возвращаемого значения Windows API. Некоторые люди могут злоупотреблять VERIFY () по этой причине. На самом деле это опасно, потому что VERIFY () нарушает идею утверждения и не может полностью разделить программный код и код отладки, что в конечном итоге может вызвать множество проблем. Поэтому специалисты рекомендуют экономно использовать этот макрос.
1. «Debug — это отладочная версия, включая дополнительную информацию о программе»
Дополнение: только версия программы DEBUG может устанавливать точки останова, выполнять пошаговое выполнение, использовать TRACE / ASSERT и другие операторы вывода отладки. REALEASE не содержит отладочной информации, поэтому имеет небольшой размер и работает быстро.
I. Проблема распределения памяти
1. Переменная не инициализирована. Следующая программа отлично работает при отладке.
30 thing * search(thing * something) 31 BOOL found; 32 for(int i = 0; i < whatever.GetSize(); i++) 33 < 34 if(whatever[i]->field == something->field) 35 < /* found it */ 36 found = TRUE; 37 break; 38 >/* found it */ 39 > 40 if(found) 41 return whatever[i]; 42 else 43 return NULL;
Но не в выпуске, потому что переменная будет автоматически инициализирована found = FALSE при отладке, но не в версии выпуска. Поэтому постарайтесь как можно больше инициализировать переменные, классы или структуры.
2. Проблема переполнения данных Такие как:
44 char buffer[10]; 45 int counter; 46 lstrcpy(buffer, «abcdefghik»);
В отладочной версии NULL буфера покрывает старшие биты счетчика, но если счетчик> 16M, проблем нет. Но в выпускной версии счетчик может быть помещен в регистр, так что NULL покрывает пространство под буфером, который может быть адресом возврата функции, что вызовет ОШИБКУ ДОСТУПА.
3. Метод выделения памяти для отладочной версии и версии выпуска отличается. Если вы подаете заявку на ele как 6 * sizeof (DWORD) = 24 байта в отладочной версии, вам фактически выделяется 32 байта (отладочная версия выделяется в единицах по 32 байта), а в версии выпуска вам выделяется 24 байта (версия выпуска) В блоке 8 байт), поэтому, если вы напишете ele [6] в отладочной версии, проблем может не быть, но в версии выпуска есть НАРУШЕНИЕ ДОСТУПА.
II. УТВЕРЖДЕНИЕ и ПРОВЕРКА 1. ASSERT не будет компилироваться в версии Release. Макрос ASSERT определяется следующим образом
47 48 #ifdef _DEBUG 49 #define ASSERT(x) if( (x) == 0) report_assert_failure() 50 #else 51 #define ASSERT(x) 52 #endif
На самом деле все сложнее, но это не имеет значения. Если к этим операторам добавить необходимый код в программе
, например
Код C ++
53 54 ASSERT(pNewObj = new CMyClass); 55 56 pNewObj->MyFunction(); В это время pNewObj в версии Release не будет выделено место Таким образом, при выполнении следующего оператора программа сообщит, что программа выполнила недопустимую ошибку операции. VERIFY можно использовать в это время: Код C ++ 57 58 #ifdef _DEBUG 59 #define VERIFY(x) if( (x) == 0) report_assert_failure() 60 #else 61 #define VERIFY(x) (x) 62 #endif
В этом случае код может быть выполнен в релизной версии.
III. Проблемы с параметрами:
Функция обработки пользовательского сообщения должна быть определена следующим образом:
afx_msg LRESULT OnMyMessage(WPARAM, LPARAM);
Возвращаемое значение должно иметь тип HRESULT, иначе отладка будет пройдена, а ошибка выпуска.
IV. Распределение памяти Обеспечьте единство создания и удаления данных: если DLL предоставляет функцию, которая может создавать данные, то DLL также должна предоставлять функцию для уничтожения данных. Создание и удаление данных должно быть на одном уровне.
V. Катастрофа DLL Люди называют несоответствие, вызванное смешиванием разных версий DLL, «адом DLL» (DLL Hell), даже сама Microsoft говорит об этом http://msdn.microsoft.com/library/techart/dlldanger1.htm) . Обратите внимание, если ваша программа использует вашу собственную DLL: 1. Нельзя смешивать библиотеки DLL отладки и выпуска вместе. Debug — это отладочная версия, а версия выпуска — это версия выпуска.
Решение состоит в том, чтобы поместить программы отладки и выпуска в каталоги отладки и выпуска основной программы соответственно.
2. Не думайте, что статическая линковка библиотеки решит проблему, это только усугубит ситуацию.
VI. Отладка в RELEASE версии:
1. Измените ASSERT () на VERIFY (). Найдите коды, определенные в «#ifdef _DEBUG», если вам нужны эти коды в версии RELEASE, удалите их из определения. Найдите код в TRACE (. ), потому что эти коды не скомпилированы в RELEASE. Пожалуйста, внимательно проверьте, стоит ли код, требуемый в RELEASE, недешево.
2. Разница, вызванная инициализацией переменных, есть такие различия в разных системах или между версиями DEBUG / RELEASE, поэтому инициализируйте переменные.
3. Появляется ли предупреждение при компиляции? Установите уровень предупреждения 3 или 4, а затем убедитесь, что во время компиляции предупреждение не появляется.
Источник: russianblogs.com
1 — Что такое отладка / Отладка / Visual C++
Отладкой можно называть процесс поиска логических ошибок в программе. Как известно ошибки бывают двух типов.
Синтаксические Логические
Синтаксические ошибки выявляются при сборке проекта и отображаются в окне Build.
По выбору которого появляется диалоговое окно выбора сборки.
Здесь можно выбрать необходимую конфигурацию и нажать на ОK. По умолчанию проект создается в отладочной версии. После сборки проекта в папке проекта появляется соответствующая папка с результатами сборки, в которой и будет лежать готовый EXE файл. Имена соответствуют именам конфигурации.
Итак, мы с Вами будем рассматривать отладку, как процесс поиска логических ошибок. Для полного использования данной возможности необходимо использовать отладочную версию сборки проекта.
![]() |
Источник: netcode.ru
Что такое отладка?
Область применения:Visual Studio
Visual Studio для Mac
Visual Studio Code
Отладчик Visual Studio — очень эффективное средство. Прежде чем приступать к его использованию, следует ознакомиться с базовыми терминами, такими как отладчик, отладка и режим отладки. Когда позднее мы будем вести речь о поиске и устранении ошибок, мы будем иметь в виду то же самое.
Отладчик и отладка
Термин отладка может иметь разные значения, но в первую очередь он означает устранение ошибок в коде. Делается это по-разному. Например, отладка может выполняться путем проверки кода на наличие опечаток или с помощью анализатора кода. Код можно отлаживать с помощью профилировщика производительности. Кроме того, отладка может производиться посредством отладчика.
Отладчик — это узкоспециализированное средство разработки, которое присоединяется к работающему приложению и позволяет проверять код. В документации по отладке для Visual Studio именно это обычно подразумевается под отладкой.
Режим отладки и выполнение приложения
При первом запуске приложения в Visual Studio его можно запустить, нажав зеленую кнопку со стрелкой Начать отладку на панели инструментов (или F5). По умолчанию в раскрывающемся списке слева отображается элемент Отладка. Если вы не имеете опыта работы с Visual Studio, может показаться, что отладка приложения — это практически то же самое, что его запуск. На самом деле эти задачи хоть и связаны, но коренным образом различаются.
Значение Отладка соответствует конфигурации отладки. Когда вы запускаете приложение (нажимая зеленую стрелку или клавишу F5) в конфигурации отладки, оно запускается в режиме отладки. Это означает, что приложение запускается с присоединенным отладчиком. В результате вы получаете полный набор функций отладки, которые можно использовать для поиска ошибок в приложении.
Если у вас открыт проект, выберите в раскрывающемся списке Отладка элемент Выпуск.
При выборе этого параметра конфигурация отладки для проекта меняется на конфигурацию выпуска. Проекты Visual Studio имеют отдельные конфигурации выпуска и отладки для вашей программы. Производится построение отладочной версии для отладки и версии выпуска для окончательного выпуска программы. Сборка выпуска оптимизирована для обеспечения максимальной производительности, а отладочная сборка лучше подходит для отладки.
Когда следует использовать отладчик
Отладчик — важнейший инструмент для поиска и устранения ошибок в приложениях. Однако большое значение имеет контекст. Важно использовать все средства, имеющиеся в вашем распоряжении, чтобы быстро устранять ошибки. Зачастую лучшим «средством» являются правильные методики написания кода. Зная, когда лучше использовать отладчик, а когда — другие средства, вы также сможете более эффективно использовать отладчик.
Следующие шаги
Из этой статьи вы узнали общие принципы отладки приложений. Теперь вы можете приступить к знакомству с процессом отладки в Visual Studio и написанию кода с меньшим количеством ошибок. В следующих статьях приводятся примеры кода на C#, но основные понятия применимы ко всем языкам, поддерживаемым средой Visual Studio.
Источник: learn.microsoft.com