Отличие debug от release android

kaktusenok

вторник, 18 июня 2013 г.

Visual Studio: Чем отличается конфигурация Debug от Release

Начинающим программистам всегда интересно, чем отличается конфигурация Debug от Release.

Привожу свой ответ на этот вопрос.

Главное различие состоит в назначении: конфигурация Debug предназначена для компиляции на этапе разработки и отладки программы, а Release — для сборки программы и последующего её использования пользователями программы.

Поэтому:

  • В конфигурации Release удаляется отладочная информация из исполняемого файла. Это приводит к уменьшению размера исполняемого файла (обычно в несколько раз).
  • Исключаются дополнительные проверки. Например, инициализированы переменные или нет:

Из приведёного рисунка видно, что в конфигурации Release никаких проверок не осуществляется, а в конфигурации Debug они есть. Так в STL, например, производятся дополнительные проверки итераторов перед операциями инкремента и декремента:

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

  • Производится оптимизация по уменьшению времени выполнения. По ссылке представлено описание возможных оптимизаций на примере компилятора C#.
  • Используются разные версии библиотек. Поэтому для запуска исполняемого файла на компьютере пользователя требуется установить соответствующие библиотеки. Для исполняемого файла, скомпилированного в конфигурации Debug, используются библиотеки с суффиксом D:

    Единственный способ установить их — скопировать необходимые DLL с компьютера разработчика. Для исполняемого файла, скомпилированного в конфигурации Release, можно установить все необходимые библиотеки из распространяемого пакета Microsoft Visual C++, чтобы избежать такой ошибки:

    В общем случае используются разные настройки проекта — для каждой конфигурации своя. В меню «Проект» > «Свойства» можно увидеть выпадающий список, определяющий конфигурацию, для которой производится настройка:

    Источник

    Урок №6. Режимы конфигурации «Debug» и «Release»

    Обновл. 7 Июн 2021 |

    Конфигурация сборки (англ. «build configuration») — это набор настроек проекта, которые определяют принцип его построения. Конфигурация сборки состоит из:

    имени исполняемого файла;

    имени директории исполняемого файла;

    имён директорий, в которых IDE будет искать другой код и файлы библиотек;

    информации об отладке и параметрах оптимизации вашего проекта.

    Интегрированная среда разработки имеет две конфигурации сборки: «Debug» (Отладка) и «Release» (Релиз).

    Конфигурация «Debug» предназначена для отладки вашей программы. Эта конфигурация отключает все настройки по оптимизации, включает информацию об отладке, что делает ваши программы больше и медленнее, но упрощает проведение отладки. Режим «Debug» обычно используется в качестве конфигурации по умолчанию.

    Конфигурация «Release» используется во время сборки программы для её дальнейшего выпуска. Программа оптимизируется по размеру и производительности и не содержит дополнительную информацию об отладке.

    Например, исполняемый файл программы «Hello, World!» из предыдущего урока, созданный в конфигурации «Debug», у меня занимал 65 КБ, в то время как исполняемый файл, построенный в конфигурации «Release», занимал всего лишь 12 КБ.

    Переключение между режимами «Debug» и «Release» в Visual Studio

    Самый простой способ изменить конфигурацию проекта — выбрать соответствующую из выпадающего списка на панели быстрого доступа:

    Переключение между режимами «Debug» и «Release» в Code::Blocks

    В Code::Blocks на панели быстрого доступа есть также выпадающий список, где вы можете выбрать соответствующий режим конфигурации:

    Заключение

    Используйте конфигурацию «Debug» при разработке программ, а конфигурацию «Release» при их релизе.

    Поделиться в социальных сетях:

    Урок №5. Компиляция вашей первой программы

    Комментариев: 16

    Здравствуйте. Спасибо, отличный курс.
    Вопрос. Как реализовать режим Release в командной строке, используя Mingw?
    Успехов. Еще раз Спасибо

    Чтобы реализовать Debug режим в консоли или коммандной строке используется дополнительный ключ для компилятор gcc или g++. Данный ключ «-g» (Например: gcc -g -c main.c -o NameProgramm). Включает отладочную информацию, которая пакуется внутрь исполняемого файла NameProgramm. Следовательно, делает его большего размера, но, при дебагинге такими программами как gdb сразу можно отобразить исходный код.

    Источник

    Tek Eye

    An Android app will execute in debug mode in the development environment, i.e. while running in the Android Studio Integrated Development Environment (IDE). The app will execute in release mode when installed from Google Play. In release mode any debug logging, StrictMode, and the debugging option must be disabled. When developing an Android app there are occasional times when detecting debug mode vs release mode is helpful. This article contains example code to show how debug mode and release mode can be determined at app runtime.

    Distinguishing Android Debug Mode Vs Release Mode

    It is possible to wrap calls to logging code, and StrictMode set up, in code that checks for debug mode. To detect Android debug vs release mode there are two objects that expose the debug flag, the ApplicationInfo class (since API Level 1) and BuildConfig (subsequent SDK releases).

    (For this Android tutorial try the given code in a simple app. This article assumes that the latest Android Studio is installed, a basic app can be created and run (here called Check Debuggable), and the code in this article can be correctly copied into Android Studio. The example code can be changed to meet your own requirements. When entering code in Studio add import statements when prompted by pressing Alt-Enter.)

    Android Debug vs Release Using ApplicationInfo Flags

    With ApplicationInfo the flags field has a debug bit. To use it in code perform a boolean And on flags with ApplicationInfo.FLAG_DEBUGGABLE, if the result is not zero the app is in debug mode (getApplicationInfo() is available from Context):

    The Old Way of Overriding the Android Debug Flag

    The debug bit used to be set via the android:debuggable attribute on the application element in AndroidManifest.xml (use the Studio Project explorer to find AndroidManifest.xml). Usually the android:debuggable attribute was not present, it was set automatically by the build tools. Being set true to allow the app to be debugged in the IDE, and set to false to turn off debugging when the final Android app’s APK was generated. Therefore, it used to be possible to force debug mode on or off by setting it true or false in the manifest file:

    However, that not longer appears to work. Now if android:debuggable is explicitly set then Studio will display a warning:

    Avoid hardcoding the debug mode; leaving it out allows debug and release builds to automatically assign one

    It’s best to leave out the android:debuggable attribute from the manifest. If you do, then the tools will automatically insert android:debuggable=true when building an APK to debug on an emulator or device. And when you perform a release build, such as Exporting APK, it will automatically set it to false. If on the other hand you specify a specific value in the manifest file, then the tools will always use it.

    This can lead to accidentally publishing your app with debug information.

    But developers on some forums now say that the android:debuggable attribute no longer works. Indeed, if set to a different value from the Gradle settings (see below) the project will not build.

    Android Debug vs Release Using BuildConfig.DEBUG

    The class BuildConfig (generated at build time) allows for build specific settings. The flag BuildConfig.DEBUG is set true when the app is running in the IDE. It is set false in the released APK, therefore BuildConfig.DEBUG mirrors the older android:debuggable value.

    To explicitly set BuildConfig.DEBUG edit the build.gradle for the app module, here turning off debugging in the IDE for the normal debug build:

    Why would you want to explicitly set debuggable to true or false? It could be used when testing an app on an Android Virtual Device (AVD) or real device close to a release. Set to false to check that a release build is not unnecessarily producing log output, or displaying test data or screens. Likewise, set it to true when loading an APK on a physical device to provide extra functionality to testers (e.g. provide an easy way to get to extra levels in a game app). However, if explicitly set the debuggable setting should always be deleted before the final shipping build, i.e. this would not be a good setting in a released APK:

    Example Code to Check for Android Debug Vs Release Mode

    Here is the simple layout used for the code that follows:

    It has already been seen that the app’s ApplicationInfo instance is read from the app’s Context:

    Which is the same as ApplicationInfo appInfo = this.getApplicationInfo(); when in the activity class. Note however, that prior to Cupcake (API level 3) ApplicationInfo needed to be obtained from the PackageManager :

    Using a reference to the app’s ApplicationInfo the flags value can be tested for the debug setting. Here it is being used to update a TextView :

    And the code to read BuildConfig.DEBUG:

    Here’s the debugging settings in action. First no debuggable setting is present and the code is running in the IDE:

    The same code running in a signed APK:

    And now running from the IDE with the debuggable flag manually set to false

    Here is the full MainActivity.java code:

    In Summary

    To detect if code is running in debug test the BuildConfig.DEBUG for true. However, a word of warning. BuildConfig.DEBUG may not be correct if checked in code packaged in a library.

    See Also

    • See the other Android Studio example projects to learn Android app programming.
    • For a full list of the articles on Tek Eye see the full site Index

    Author: Daniel S. Fowler Published: 2013-08-31 Updated: 2018-01-06

    Do you have a question or comment about this article?

    (Alternatively, use the email address at the bottom of the web page.)

    ↓markdown↓ CMS is fast and simple. Build websites quickly and publish easily. For beginner to expert.

    Free Android Projects and Samples:

    Источник

    Пара историй про отличия Release от Debug

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

    История 1

    Собственно, началось все с того, что пришел баг о том что при некоторых операциях приложение вылетает. Это бывает часто. Баг не захотел воспроизводиться в Debug-версии. Это порой бывает. Поскольку в приложении часть библиотек была написано на C++, то первой мыслью было что-то вроде «где-то забыли переменную проинициализировать или что-то в этом духе». Но на деле суть бага крылась в управляемом коде, хотя без неуправляемого тоже не обошлось.

    А код оказался примерно следующим:

    public Wrapper()
    <
    this .Obj = CreateUnmObject();
    >

    Wrapper()
    <
    this .Dispose( false );
    >

    protected virtual void Dispose( bool disposing)
    <
    if (disposing)
    <
    >

    this .ReleaseUnmObject( this .Obj);
    this .Obj = IntPtr .Zero;
    >

    public void Dispose()
    <
    this .Dispose( true );
    GC.SuppressFinalize( this );
    >
    >

    * This source code was highlighted with Source Code Highlighter .

    В принципе, практически каноническая реализация шаблона IDisposable («практически» — потому, что нет переменной disposed, вместо нее обнуление указателя), вполне стандартный класс-обертка неуправляемого ресурса.

    Использовался же класс примерно следующим образом:

    * This source code was highlighted with Source Code Highlighter .

    Естественно, что внимательный читатель сразу обратит внимание, что объекта wr надо вызвать Dispose, то есть обернуть все конструкцией using. Но на первый взгляд, на причину падения это не должно повлиять, так как разница будет в том детерминировано ли очистится ресурс или нет.

    Но на самом деле разница есть и именно в релизной сборке. Дело в том, что объект wr становится доступным сборщику мусора сразу после начала выполнения метода DoCalculations, ведь больше нет ни одного «живого» объекта, кто на него ссылался бы. А значит wr вполне может(а так оно и происходило) быть уничтожен во время выполнения DoCalculations и указатель, переданный в этот метод становится невалидным.

    Если обернуть вызов DoCalculations в using (Wrapper wr = new Wrapper())<. >, то это решит проблему, поскольку вызов Dispose в блоке finally, не даст жадному сборщику мусора «съесть» объект раньше времени. Если же по какой-то причине мы не можем или не хотим вызывать Dispose (к примеру WPF этот шаблон совсем не жалует), то придется вставлять GC.KeepAlive(wr) после вызова DoCalculations.

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

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

    История 2

    Жил-был проект, где для доступа к ресурсам использовался менеджер, который по строковому ключу доставал из заданной сборки различного вида ресурсы. С целью облегчения написания кода был написан следующего вида метод:

    public string GetResource( string key)
    <
    Assembly assembly = Assembly .GetCallingAssembly();
    return this .GetResource(assembly, key);
    >

    * This source code was highlighted with Source Code Highlighter .

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

    Чтобы «почувствовать разницу» предлагается следующий пример:

    dll1:
    public class Class1
    <
    public void Method1()
    <
    Console .WriteLine( new StackTrace());
    >
    >

    dll2:
    public class Class2
    <
    public void Method21()
    <
    this .Method22();
    >

    public void Method22()
    <
    ( new Class1()).Method1();
    >
    >

    dll3:
    class Program
    <
    static void Main( string [] args)
    <
    ( new Class3()).Method3();
    >
    >
    class Class3
    <
    public void Method3()
    <
    ( new Class2()).Method21();
    >
    >

    * This source code was highlighted with Source Code Highlighter .

    Если скомпилировать в дебажной конфигурации(или если запускать процесс из-под студии) то получим честный стек вызовов:
    в ClassLibrary1.Class1.Method1()
    в ClassLibrary2.Class2.Method22()
    в ClassLibrary2.Class2.Method21()
    в ConsoleApplication1.Class3.Method3()
    в ConsoleApplication1.Program.Main(String[] args)

    Если собрать под .Net версии до 3.5 включительно в релизе:
    в ClassLibrary1.Class1.Method1()
    в ClassLibrary2.Class2.Method21()
    в ConsoleApplication1.Program.Main(String[] args)

    А под .Net 4 в релизной конфигурации то и вовсе получим:
    в ConsoleApplication1.Program.Main(String[] args)

    Мораль здесь проста — не стоит привязывать логику к стеку вызовов, равно как и удивляться необычному стеку в исключениях в логе релизной версии. В частности, если вы пытаетесь найти причину исключения исключительно по его стеку вызовов, то стоит учитывать, что если стек заканчивается на методе Method1, то в коде оно(исключение) могло быть сгенерировано в одном из небольших методов, которые вызываются в теле Method1.

    Так же на всякий случай стоит помнить, что можно запретить компилятору встраивать метод пометив его атрибутом [MethodImpl(MethodImplOptions.NoInlining)], эдакий аналог __declspec(noinline) в VC++.

    Вместо заключения

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

    Источник

    Читайте также:  Как перенести беседы whatsapp с андроида
  • Оцените статью