Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Common reasons for bugs in release version not present in debug mode

People also ask

What is difference between release and debug mode?

By default, Debug includes debug information in the compiled files (allowing easy debugging) while Release usually has optimizations enabled. As far as conditional compilation goes, they each define different symbols that can be checked in your program, but they are language-specific macros.

Can you debug in release mode?

You can now debug your release build application. To find a problem, step through the code (or use Just-In-Time debugging) until you find where the failure occurs, and then determine the incorrect parameters or code.

Is release mode faster than debug?

Debug Mode: In debug mode the application will be slow. Release Mode: In release mode the application will be faster.


Many times, in debug mode in C++ all variables are null initialized, whereas the same does not happen in release mode unless explicitly stated.

Check for any debug macros and uninitialized variables

Does your program uses threading, then optimization can also cause some issues in release mode.

Also check for all exceptions, for example not directly related to release mode but sometime we just ignore some critical exceptions, like mem access violation in VC++, but the same can be a issue at least in other OS like Linux, Solaris. Ideally your program should not catch such critical exceptions like accessing a NULL pointer.


A common pitfall is using an expression with side effect inside an ASSERT.


I've been bitten by a number of bugs in the past that have been fine in Debug builds but crash in Release builds. There are many underlying causes (including of course those that have already been summarised in this thread) and I've been caught out by all of the following:

  • Member variables or member functions in an #ifdef _DEBUG, so that a class is a different size in a debug build. Sometimes #ifndef NDEBUG is used in a release build
  • Similarly, there's a different #ifdef which happens to be only present in one of the two builds
  • The debug version uses debug versions of the system libraries, especially the heap and memory allocation functions
  • Inlined functions in a release build
  • Order of inclusion of header files. This shouldn't cause problems, but if you have something like a #pragma pack that hasn't been reset then this can lead to nasty problems. Similar problems can also occur using precompiled headers and forced includes
  • Caches: you may have code such as caches that only gets used in release builds, or cache size limits that are different
  • Project configurations: the debug and release configurations may have different build settings (this is likely to happen when using an IDE)
  • Race conditions, timing issues and miscellanous side-effects occurring as a result of debug only code

Some tips that I've accumulated over the years for getting to the bottom of debug/release bugs:

  • Try to reproduce anomalous behaviour in a debug build if you can, and even better, write a unit test to capture it
  • Think about what differs between the two: compiler settings, caches, debug-only code. Try to minimise those differences temporarily
  • Create a release build with optimisations switched off (so you're more likely to get useful data in the debugger), or an optimised debug build. By minimising the changes between debug and release, you're more likely to be able to isolate which difference is causing the bug.

Other differences might be:

  • In a garbage-collected language, the collector is usually more aggressive in release mode;
  • Layout of memory may often be different;
  • Memory may be initialized differently (eg could be zeroed in debug mode, or re-used more aggressively in release);
  • Locals may be promoted to register values in release, which can cause issues with floating point values.