Допустим, я предпочитаю отлаживать выпускную сборку своего программного обеспечения во время разработки. Какие проблемы я могу пропустить, делая это?
задан 09 дек.
Johann Gerell
заголовок = напротив основного текста вопроса? — Pleun
Ваш заголовок и вопрос противоположны. — AShelly
Может быть, он написал один в отладке. как мета! — Simon Cowen
6 ответы
- В сборке Release есть некоторые оптимизации. Вы можете увидеть полный список оптимизаций здесь. Ни один из них не должен влиять на результат программы.
- Если у вас где-то есть директива DEBUG, она останется. Обратите на это особое внимание, так как это может изменить целые функции.
- Debug.Asserts завершится ошибкой в режиме отладки, но НЕ в режиме выпуска.
ответ дан 09 дек ’11, 15:12
Хм, интересно, отличается ли код, обработанный JIT поверх релизной сборки, от кода, обработанный JIT по сборке отладки, помимо оптимизаций, которые Эрик предлагает в этом посте. — хитрый
Верно, этот список оптимизаций — это выполненные оптимизации на Ил. IL — это не то, что работает, IL — это просто вход для джиттера. Дрожание знает, была ли программа скомпилирована для отладки или для розничной продажи, и знает, отлаживаете ли вы ее прямо сейчас или нет, и именно дрожание может решить, следует ли соответствующим образом более сильно оптимизировать фактическую работающую программу. — Эрик Липперт
Рекрутинг в одноклассниках 2022 (бесплатный метод)
Вероятно, самым раздражающим из них является «неизменяемый флаг, используемый для подачи сигнала об остановке потока, вызывает взаимоблокировку в режиме выпуска, но не в режиме отладки».
Это часто встречается как:
flag = false; Thread t = new Thread( o => < while(!flag) < // do stuff >>); t.Start(); // main thread does some work flag = true; t.Join(); // will never return in release mode if flag is not volatile
Это происходит из-за оптимизации компилятора в режиме выпуска, т.к. flag переменная кэшируется ядром потока t и поэтому он не может видеть обновленное значение flag .
ответ дан 09 дек ’11, 15:12
Это причина, по которой вы должен сделайте хотя бы часть вашей отладки в режиме выпуска. — Ашелли
В релизе есть некоторые оптимизации, сделанные компилятором. Так что, возможно, есть некоторые переменные, которые вы не сможете прочитать, или некоторые встроенные функции. Но в глобальном масштабе вы сможете указать, где проблема.
ответ дан 09 дек ’11, 15:12
Это не столько проблемы, которые вы можете пропустить, когда пытаетесь отладить релизную сборку, сколько то, что вы не можете сделать или работать «странно»:
- Некоторые переменные могут быть оптимизированы, поэтому вы не сможете их проверить.
- свойства и/или методы могут быть встроены, так что кодовая позиция будет потеряна
ответ дан 09 дек ’11, 15:12
Вы можете пропустить переполнение буфера. Код отладки добавляет отступы вокруг памяти, доступной для вашей программы, а сборка выпуска — нет. Таким образом, отладчик может обнаруживать и предупреждать, когда вы записываете ненужную память в отладочную сборку. В релизной сборке та же проблема может остаться незамеченной, пока пользователь не введет один специальный ввод, который приведет к сбою всего.
Отладочная Плата AtMega16
То же самое относится и к использованию неинициализированных переменных. Отладочная сборка обнаружит это, релизная сборка — нет. И по закону Мерфи последнее изменение перед выпуском изменит неинициализированную переменную на что-то, что вызовет проблемы с разделом, который вы решили не тестировать повторно.
ответ дан 09 дек ’11, 15:12
На самом деле это относится в основном к C/C++, не знаю, чем здесь отличается C#. — Ашелли
Предопределенные конфигурации отладки и выпуска управляют параметрами сборки, такими как константа DEBUG и оптимизация кода.
Код условной отладки (#IF DEBUG) не будет выполняться в режиме выпуска. Как уже было сказано, оптимизация также может скрывать переменные.
Еще одна вещь, которая может помешать вам правильно отладить, заключается в том, генерируются ли файлы pdb или нет (информация о сборке/расширении/отладке), если нет, VS не сможет показать вам исходный код приложения, которое вы отлаживаете.
ответ дан 09 дек ’11, 15:12
Источник: stackovergo.com
Русские Блоги
Недавно он разрабатывается, потому что сервер SVN находится на моем компьютере. Система сначала настроена на моем компьютере. Затем опубликуйте это для всех. То есть я нашел эту проблему в процессе.
Вероятно, это так. Я не знаю, когда я сделаю свой режим выполнения в качестве режима выпуска. Затем я загрузил на сервер, и будет ошибка, когда другие загружали его. Хотя появление этой проблемы было быстро решено, проблемы все еще должны быть обобщены хорошо.
один, Первое, что нужно понять, это отладка, и первое, что нужно понять, это отладка и Release Различия.
Я много сказал в этом интернете. Я хотел бы сказать:
Debug Обычно его называют версией отладки, которая содержит информацию отладки и не оптимизирует какую -либо оптимизацию, которая удобна для программистов для отладки программ. Release Он называется версия релиза, которая часто оптимизирует различные оптимизации, так что программа является лучшей в размере кода и скорости работы, чтобы пользователи могли хорошо использовать ее.
Debug а также Release Реальная разница — это набор параметров компиляции. Сущность Параметры для двух перечислены ниже
/Mdd /mld или /mtd
Используйте библиотеку времени выполнения отладки
Выключите переключатель оптимизации
Эквивалент #DEFINE_DEBUG, включите компиляцию и переключатель кода компиляции и отладки (в основном для функции ASSERT)
Создайте редактирование и продолжение базы данных, так что если исходный код изменяется во время процесса отладки, он не должен быть повторно
Может помочь захватить ошибки памяти
Откройте минимальный переключатель тяжелой ссылки, чтобы сократить время ссылки
/MD /ML или же /MT
Используйте выпуск версии выпуска библиотеки функций
Оптимизировать переключатель, чтобы минимизировать программу
Отключить компиляцию условий и переключение кода ввода в эксплуатацию ( Это не компиляция assert функция )
Объединенная и дублированная строка и поместите строку постоянную, чтобы прочитать только память, чтобы предотвратить изменение
На самом деле отладка а также Release Там нет существенной границы. Это всего лишь набор параметров компиляции, и компилятор действует только в соответствии с запланированными параметрами. Фактически, мы можем даже изменить эти параметры для получения оптимизированной версии отладки или выпуска оператора отслеживания.
Так где же скомпилируются две вещи? Конечно, это показывает, что эти две вещи не только относятся к какой .dll Файл является группой, сгенерированной в этом режиме .dll собирать. Говоря, я думаю, все должны понимать. Фактически bin Отладка под папкой а также Release Две папки.
Затем мы анализируем причину ошибки: я не загрузил меня, когда загрузил систему bin Папка, потому что я сказал в предыдущем блоге (адрес соединения http://blog.csdn.net/hy6688_/article/details/9500149). Конечно, при загрузке появятся другие участники Найдите определенную сборку », потому что вы не сгенерировали.
Конечно, эта проблема должна быть предотвращена от аналогичных проблем. Подвести итог соответствующих проблем:
В какой степени Release Издание будет неправильно
С приведенным выше введением давайте посмотрим на эти варианты один за другим Release Как ошибка версии?
1. Runtime Library :
Какую библиотеку функций работы времени обычно влияет только на производительность программы. Отладочная версия Runtime Library Он содержит отладку информации и использует некоторые механизмы защиты, чтобы помочь найти ошибки, поэтому производительность не так хороша, как публикация. Предоставлено компиляторами Runtime Library Обычно очень стабильный и не вызовет Release Ошибка издания; Debug из Runtime Library Увеличьте обнаружение ошибок, таких как распределение памяти кучи, иногда появляется Debug Неправильно, но Release нормальное явление. Что следует указать, так это то, что если Debug Что -то не так, даже если Release Обычно программа должна иметь Bug Это может быть только Release Версия версии не показала определенной операции.
2. Оптимизация:
Это главная причина ошибок, потому что исходная программа в основном напрямую переводится при выключении и оптимизации, а компилятор сделает ряд предположений после открытия оптимизации. Есть в основном следующие типы ошибок:
(1) Указатель рамки (Frame Pointer) Опущено (сокращено (относится к FPO ):
Во время процесса вызова функции вся информация о вызове (адрес возврата, параметры) и автоматические переменные размещаются в стеке. Если функция функции отличается от реализации (параметр, возвращаемое значение, метод вызова), возникнет ошибка -но Debug Под пути, доступ к стеке проходит EBP Адрес, сохраненный регистром, реализован. Если нет никаких ошибок, таких как граница с перекрестной партией (или «мало» на границе), функция обычно может быть выполнена; Release Под методом оптимизация будет опустить EBP Место проведения базы стека, так что ошибка обратного адреса может вызвать ошибку обратного адреса через глобальный указатель. C++ Большинство из этих ошибок обнаруживаются с помощью сильных типов характеристик, но если используется обязательное преобразование типа, оно не будет работать. Вы можете Release Обязательное присоединение в версии /Oy- Опция компиляции опущена для отключения указателя кадра, чтобы определить, такие ошибки. Такие ошибки обычно включают:
● MFC Функция ответа сообщения записывает ошибки. Правильное должно быть
afx_msg LRESULT OnMessageOwn(WPARAM wparam,LPARAM lparam);
ON_MESSAGE Макро содержит обязательное преобразование типа. Один из способов предотвратить эту ошибку -повторно определить ON_MESSAGE Макро, добавьте следующий код в stdafx.h В #include «afxwin.h» после) , Компиляция Когда функция неверна, будет сообщена ошибка
#define ON_MESSAGE(message, memberFxn) /
CWnd::*)(WPARAM, LPARAM) > (,
(2) volatile Тип переменной:
volatile Скажите компилятору, что переменная может быть изменена неизвестным способом за пределами программы (например, систем, другие процессы и потоки). Чтобы повысить производительность программ, программы оптимизации часто вкладывают некоторые переменные в регистрах (аналогично register Ключевые слова и другие процессы могут только изменять память, в которой находится переменная, и значение в регистре не изменилось. Если ваша программа многочисленна, или если вы обнаружите, что значение переменной не соответствует ожидаемому, и вы убеждены, что установили ее правильно, вы, вероятно, столкнетесь с такой проблемой. Эта ошибка иногда проявляется в качестве самой быстрой ошибки оптимизации, и минимальная оптимизация является нормальной. Добавьте подозрительные переменные, которые вы думаете volatile Пытаться.
(3) Оптимизация разнообразия:
Программы оптимизации оптимизируют переменные на основе использования переменных. Например, в функции есть неиспользованная переменная, Debug В версии это может охватить множество кросс -бордюра, и Release В версии эта переменная, вероятно, будет оптимизирована. В настоящее время массив Cross -Bordder может уничтожить полезные данные в стеке. Конечно, реальная ситуация будет намного сложнее, чем эта. Ошибки, связанные с этим, включают:
● Незаконные посещения, в том числе массив кросс -бордюр, ошибки указателя и т. Д. Например
void fn(void) < int i; i = 1; int a[4]; < int j; j = 1; >[-1] = 1; // Конечно, ошибка не будет настолько очевидной, например, настройка является переменной a[4] = 1; >
j Хотя прицел был произведен во множестве пересечения границы, ее пространство не было восстановлено, поэтому i а также j Он покроет крест -балл. а также Release Из-за i 、 j Он может быть оптимизирован без его большого эффекта, который разрушается.
3. _DEBUG а также NDEBUG :
Определение _DEBUG час, assert() Функция будет составлена, и NDEBUG Время от времени не скомпилируется. Помимо, VC++ Есть также ряд утверждений. Это включает:
ANSI C утверждение void assert(int expression );
C Runtime Lib утверждение _ASSERT( booleanExpression );
MFC утверждение ASSERT( booleanExpression );
ASSERT_KINDOF( classname, pobject );
ATL утверждение ATLASSERT( booleanExpression );
Кроме того, Trace () Компиляция Macro также страдает _DEBUG контроль.
Все эти утверждения только в Debug Только скомпилировано в версии и в Release Версия была проигнорирована. Единственное исключение — это VERIFY() Сущность На самом деле эти макросы называются assert() Функции, но некоторые отладки, связанные с библиотекой. Если вы добавите какой -либо программный код в эти макросы, а не только логическое выражение (например, вызов функции, который может изменить значение значения переменной Подожди), тогда Release Издание не выполнят эти операции, что вызывает ошибки. Новичкам легко допускать такие ошибки, а метод поиска очень прост, потому что эти макросы были перечислены выше, если они используют VC++ из Find in Files Функцию можно найти во всех этих макро -местах во всех файлах проекта. Кроме того, некоторые мастера также могут присоединиться #ifdef _DEBUG Обратите внимание на сборник условий, таких как.
Кстати, стоит упомянуть VERIFY() Макро, этот макрос позволяет вам поместить код программы в логическое выражение. Этот макрос обычно используется для проверки Windows API Возвращаемое значение. Некоторые люди могут злоупотреблять этой причиной VERIFY() На самом деле это опасно, потому что VERIFY() Нарушение идеи утверждений не может быть полностью отделено от кода программы и отладки кода, и это может в конечном итоге принести много проблем. Поэтому эксперты рекомендуют пытаться использовать этот макрос максимально.
4. /GZ Параметры: эта опция сделает следующие вещи
(1) Инициировать память и переменные.
Включают 0xCC Инициализировать все автоматические переменные, 0xCD ( Cleared Data ) Память, назначенная в инициализированной куче (то есть динамическое распределение памяти, например, как new ), 0xDD ( Dead Data ) Заполнение освобождения памяти свай (например, delete ), 0xFD( deFencde Data ) Инициализированная защищенная память ( debug Версия добавляется в защитную память до и после динамического распределения памяти для предотвращения доступа к перекрестному борьбе). Слова в кронштейнах являются предложенными словами Microsoft. Преимущество этого заключается в том, что эти значения очень велики, и невозможно быть указателем (и больше (и 32 Указатель в системе положения редко бывает нечетным значением, и указатель нечетных чисел в некоторых системах вызовет ошибки времени выполнения). Он редко встречается как значение, и эти значения легко идентифицировать, так что это очень выгодный Debug Открытие в версии Release Издание будет столкнуться с ошибками. Следует отметить, что многие думают, что компилятор будет использовать его 0 Для инициализации переменных это неправильно (и это не способствует поиску ошибок).
(2) При вызове функции по указателю функции сопоставление вызова функции можно проверить, проверив указатель стека. (Предотвратить исходную форму не совпадать)
(3) Функция вернулась, чтобы проверить указатель стека, чтобы подтвердить, что она не была изменена. (Чтобы предотвратить посещение перекрестного парня не соответствовать исходной форме, его можно примерно смоделировать со вторым элементом. FPO )
обычно /GZ Варианты вызовут Debug Издание неверно Release Нормальное явление является потому, что Release Неподготовленные переменные в версии являются случайными, что может сделать точку указателя на эффективный адрес и скрыть незаконную доступ.
Кроме того,/Gm /GF Варианты относительно небольшие, и их эффекты очевидны, и их легче найти.
Хотя эти ошибки, упомянутые позже, не поняты. Но через эту проблему. У меня более глубокое понимание того, в чем разница между отладкой и выпуском, и я считаю, что эти задачи не должны быть бесполезными.
Источник: russianblogs.com
Безопасная отладка вашего приложения в продакшене
Production (продакшен, прод) — версия продукта, прошедшая все стадии тестирования и выложена онлайн / установлена клиенту.
Проведите пальцем вверх, проведите пальцем вниз, покружитесь и постучите ногой в ритме “Макарена”. Теперь у вас есть доступ к ✨ секретному меню разработчика ✨.
Некоторые из самых ранних известных чит-кодов и секретных меню отладки относятся к 1980-м годам, но с учетом современных технологий и безопасности — какой вариант лучше всего подходит для вашего приложения?
Как инженеры, мы тратим так много времени на создание наилучшего опыта, который только можно вообразить, для пользователя; но как много времени уходит на то, чтобы упростить выполнение цикла для нас? Хорошо разработанное меню отладчика может сэкономить часы на тестировании новых функций или устранении существующих ошибок.
Возможности бесконечны, они ограничены только вашим воображением и усилиями, которые вы готовы приложить. Изменение переключателей функций, сброс кешей, смена среды разработки, просмотр логов или текущего состояния — вот лишь несколько идей того, чего можно достичь.
В Sidetrack наше меню отладки в приложении позволяет нам быстро просматривать отдельные кэшированные сообщения, которые используются для проецирования последней служебной информации. Поскольку одно вью в нашем приложении может представлять собой сумму 100 различных сообщений, одна ошибка в начале цепочки может быстро привести к отображению неверной информации во многих местах.
Но где живет меню отладки и кто должен иметь к нему доступ? В зависимости от ваших личных факторов риска, типа проблем, с которыми вы обычно сталкиваетесь, и ваших методов разработки, вам может пригодиться одно или несколько решений из этого поста.
Варианты на выбор
Симулятор и Отладочные Сборки
Используя директивы компилятора, вы можете определить код, который не должен компилироваться в определенные сборки вашего приложения.
Например, #if DEBUG гарантирует, что обернутый код не будет включен в релизные сборки вашего приложения. Аналогично, #if targetEnvironment(simulator) будет компилироваться только когда таргетом сборки вы назначаете свой iOS-симулятор.
Это очень простое решение, и у конечных пользователей нет возможности получить доступ к этой функции, поскольку ее просто не будет в их версии приложения. Однако, если ваша цель — получить доступ к меню отладки в продакшене, этот вариант не поможет.
Когда SwiftUI был выпущен в начальной стадии, превью были заключены в директиву #if DEBUG, чтобы они не раздували двоичный файл App Store. Начиная с Xcode 11 Apple делает это автоматически. Аналогично, такие инструменты, как FLEX и Inject, отключают определенные функциональные возможности при компиляции для релизных сборок, демонстрируя хороший пример использования.
TestFlight
Проверив URL-расписку в App Store, можно определить, была ли установлена сборка вашего приложения через TestFlight. Это может быть полезно для включения возможностей отладки для определенных подписанных пользователей.
Однако нет различий между внутренними группами TestFlight и различными внешними группами TestFlight (что может означать предоставление доступа к большей группе, чем вы предполагали). Кроме того, это решение не работает для приложений Catalyst или приложений, распространяемых через TestFlight для macOS. Он официально не поддерживается Apple и может отказать в любой момент.
Вы можете рассмотреть возможность создания отдельной конфигурации сборки TestFlight. Это позволит вам использовать директивы компилятора (похожие на #if DEBUG) и создавать специальные сборки только для TestFlight. Вы можете отправлять разные сборки разным группам, что даст вам полный контроль.
Однако это приводит к большим накладным расходам, и можно легко случайно отправить в App Store не ту сборку. Подобное наблюдалось неоднократно ранее, даже самой Apple, которая много раз случайно отправляла сборку, содержащую инструменты разработчика, в открытый доступ.
Жесты
Жесты — это искусство скрывать функциональность на виду, просто за счет незаметности. Пользователи привыкли к некоторому количеству жестов, но вы определенно можете назначить дополнительный шаг для разблокировки меню отладки, если пользователь знает правильную комбинацию.
Konami Code — это чит-код, состоящий из последовательности 10 нажатий кнопок, ставший популярным в 1980-х годах благодаря игре Contra, ввод которой давал игроку 30 дополнительных жизней. В настоящее время он был адаптирован для мобильных устройств с использованием жестов смахивания. Есть много библиотек с открытым исходным кодом, обеспечивающих такое поведение — я знаю это, потому что, если вы проверите страницу благодарностей с открытым исходным кодом ряда крупных приложений, вы можете просто найти ссылку на нее.
Жесты вполне могут выполнять свою работу, но они небезопасны и на них можно легко наткнуться. Если вы используете их, пожалуйста, подумайте о пользователях невизуальных вспомогательных технологий и о том, как это может повлиять на их работу.
Схемы URL и Вводы Текста
Определить пользовательскую схему URL в iOS так же просто, как добавить пару строк в ваш Info.plist и обработать URL в файле AppDelegate или блоке onOpenURL в SwiftUI. Если у вас есть поле ввода текста, например строка поиска, вместо URL вы можете использовать его значение.
Это позволит тестовому пользователю ввести URL, например sidetrack://super-secret-debug-menu, в приложение, такое как Safari, и ваше приложение предоставит ему доступ к меню отладки.
Однако подобные секретные строки и URL-адреса могут быть легко обнаружены, если пользователь достаточно решителен. Например, в приложении iOS Phone есть несколько обнаруженных номеров, при вызове которых открывается доступ к скрытым функциям.
Тестовые Аккаунты
Если ваше приложение поддерживает вход в систему, вы можете обнаружить, что использование этой системы — отличный способ разблокировать функции отладки для определенных пользователей. Это может быть достигнуто либо путем жесткого кодирования идентификаторов пользователей в приложении (что потребует изменения в релизной версии приложения), либо путем добавления нового параметра в отклик профиля пользователя (однако опасайтесь достоверности отклика!)
Часто это может быть очень простой вариант, построенный поверх существующей функциональности. Однако не у всех есть возможность входа в их приложении, а в действительности, вы все равно можете захотеть получить доступ к меню отладки, когда вы не вошли в систему.
Доверенные Профили (Наше Решение)
Решение, к которому мы пришли в Sidetrack, заключалось в использовании профиля конфигурации. Это особый вид сертификата, который можно создать с помощью Keychain Access и установить на свои мобильные устройства в качестве пользовательского профиля. Затем ваше мобильное приложение может определить наличие этого пользовательского профиля, проверив файл сертификата, встроенный в двоичный файл приложения.
Несмотря на небольшое усложнение, это позволяет решить все основные проблемы, возникающие при использовании других вариантов. Пользователь не может случайно наткнуться на это, и это не требует никакой существующей функциональности в вашем приложении. Он работает как с отладочными, так и с релизными сборками, независимо от того, где и как они распространяются.
Больше всего мне нравится то, что один и тот же сертификат можно использовать на неограниченном количестве устройств и приложений. Это идеально подходит как для независимых разработчиков, так и для компаний, которым нужно единое решение, которое работает для всех их продуктов и команд.
Вы также можете настроить несколько сертификатов, разблокировать различные уровни привилегий или указать даты истечения срока действия для подрядчиков или гостей, которым нужен доступ только в течение установленного периода времени.
Но как именно это работает? Что ж, он опирается на основу безопасности Apple, а точнее на функцию SecTrustEvaluate, которая позволяет нам оценить, доверяем ли мы данному сертификату (профилю, который загружается из двоичного файла приложения). Поскольку сертификат использует пользовательский центр подписи, это значение будет истинным только в том случае, если на устройстве установлен специальный профиль конфигурации, который мы генерируем отдельно и который связан с центром подписи. Только соответствующий профиль приведет к успешному выполнению кода.
В этом Gist мы предоставили пошаговые инструкции о том, как создавать собственные профили и сертификаты с кодом Swift, необходимым для подтверждения доверия. Мы также работаем над инструментом командной строки с открытым исходным кодом, чтобы сделать его доступным для всех, так почему бы не отметить наш репозиторий и не следить за уведомлениями о будущих обновлениях?