It is often asked if debug runs normally but release fails. Previous discussions are often empirical and do not point out what the real cause is, and it usually takes luck to find out the real reason. Recently I read some of these posts, to share with you.
--------------------------------------
This article mainly includes the following content:
The essential difference between 1.Debug and release compiling methods
2. In which case the release version will be wrong
2. How to "Debug" release version of the program
--------------------------------------
Discussion on the essential difference between debug and release
First, Debug and release
The essential difference between compiling methods debug is often referred to as a debug version, which contains debugging information and is not optimized for programmers to debug programs. Release is known as a publish version, it is often a variety of optimizations, so that the code size and speed of the program is optimal, so that users are very good to use. The real secret of debug and release is a set of compilation options. The following lists the options for both (there are, of course, other things, such as/FD/FO, but
Differences are not important, usually they will not cause release errors, not discussed here) Debug version:/MD
D/MLD or/MTD use Debugruntimelibrary (Debug version of runtime function library)/od turn off the tuning switch/d "_DEBUG" equivalent to #define_debug, open the Compile debug code switch (mainly for the Assert function)/ Zi Create editandcontinue (edit continue) database, so that if you modify the source code without recompiling/gz during debugging, you can help capture memory errors/gm turn on the Minimize-link switch and reduce the link-time release version:/MD/ML or/ MT uses the release version of the runtime function library/o1 or/o2 optimization switch to make the program minimum or fastest/"ndebug" shutdown condition compile debug code switch (that is, do not compile assert function)/GF merge duplicate strings and place string constants in read-only memory to prevent modification. There is no intrinsic boundary between debug and release, they are just a collection of compilation options, and the compiler simply acts on the predefined options. In fact, we can even modify these options to get optimized debug versions or release versions with trace statements.
Second, in which case release version will be wrong
With the above description, let's take a look at these options individually to see how release errors are generated
1.RuntimeLibrary: Link which run-time function library usually only has an impact on the performance of the program. The debug version of the runtimelibrary contains debugging information and has some protection mechanisms to help identify errors, so performance is not as good as the release version. Compiler-supplied runtimelibrary are usually stable and do not cause release errors, but because debug runtimelibrary enhances error detection, such as heap memory allocations, there are sometimes debug errors but release normal behavior. It should be noted that, if debug error, even if the release is normal, the program must be a bug, but may be released version of a run did not show it.
2. Optimization: This is the primary cause of the error, because the source program is basically translated directly when the optimization is turned off, and the compiler makes a series of assumptions when the optimization is turned on. Such errors are mainly as follows: (1) frame pointer (Framepointer) ellipsis (FPO): In the function call process, all call information (return address, parameters) and automatic variables are placed on the stack. If the Declaration and implementation of the function are different (parameters, return value, call mode), it will produce errors ———— but in the debug mode, the stack access through the EBP register to save the address implementation, if there is no array of errors such as error (or "Not much"), the function can normally ; In release mode, optimizations omit the EBP stack base address pointer, so accessing the stack via a global pointer causes the return address error to be a program crash. The strongly typed nature of C + + can check out most of these errors, but not if you use coercion type conversions. You can force the/oy-compilation option in release version to turn off frame pointer ellipsis to determine whether this type of error occurs. This type of error usually has: MFC message response function write error. The correct should be Afx_msglresultonmessageown (Wparamwparam,lparamlparam); On_message macros contain coercion type conversions. One way to prevent this error is to redefine the On_message macro, add the following code to stdafx.h (after #include "afxwin.h"), and the compiler will complain when the function is in the wrong shape #undefon_message#defineon_ Message (MESSAGE,MEMBERFXN)/{message,0,0,0,afxsig_lwl,/(afx_pmsg) (AFX_PMSGW) (Static_cast<lresult Call/cwnd::*) (Wparam,lparam) > (&MEMBERFXN)}, (2) volatile type variable: volatile tells the compiler that the variable may be modified in an unknown way outside of the program (such as system, other processes, and threads). In order to improve program performance, the optimizer often places variables in registers (similar to the Register keyword), while other processes can only modify the memory in which the variable resides, while the value in the register does not change. If your program is multi-threaded, or you find that the value of a variable does not match what you expected and you are sure you have set it correctly, you are likely to experience this problem. This type of error can sometimes be manifested as a program with the fastest optimization error and minimal optimization normal. Try to add volatile to the variable you think is suspicious. (3) Variable optimization: The optimizer optimizes variables based on the use of variables.For example, there is an unused variable in the function that in the debug version might mask an array out of bounds, and in release, the variable is likely to be tuned, and the array's bounds will break the useful data in the stack. Of course, the actual situation would be much more complicated than that. The errors associated with this are: illegal access, including array bounds, pointer errors, and so on.
For example voidfn (void) {inti;i=1;inta[4];{ Intj;j=1;} a[-1]=1;//of course.
Errors are not so obvious, for example, the subscript is a variable a[4]=1; J Although the scope is out when the array is out of bounds,
The space is not retracted, so I and J will cover the boundaries. And the release version because I, J does not have a big role
may be optimized, causing the stack to be corrupted.
3._debug and Ndebug: When _DEBUG is defined, the Assert () function is compiled, and Ndebug is not compiled. In addition, VC + + also has a series of assertion macros. This includes: Ansic asserts Voidassert (intexpression); Cruntimelib asserts _assert (booleanexpression); _asserte (booleanexpression); MFC assertion assert (Booleanexpression); VERIFY (booleanexpression); Assert_valid (Pobject); Assert_kindof (Classname,pobject); ATL asserts Atlassert (booleanexpression); In addition, the compilation of TRACE () macros is also controlled by _DEBUG. All of these assertions are compiled only in the debug edition and are ignored in release editions. The only exception is verify (). In fact, all of these macros invoke the Assert () function, except that some debugging code related to the library is attached. If you add any program code to these macros, not just Boolean expressions (such as assignment, function calls that can change the value of variables, etc.), then the release version does not perform these operations, causing errors. Beginners are very easy to make such errors, the search method is also very simple, because these macros have been listed above, as long as the use of VC + + FindInFiles features in all the documents found in the project where the macros to check again. In addition, some experts may also join the #ifdef_debug such as conditional compilation, also
Be careful. Incidentally, it's worth mentioning the verify () macro, which allows you to put program code in a Boolean expression
In This macro is typically used to check the return value of the WINDOWSAPI. Some people may abuse verify for this reason.
(), in fact this is dangerous, because verify () violates the assertion of the idea that the program code and debugging code
A complete separation may eventually lead to a lot of trouble. Therefore, experts recommend that you use this macro as little as possible.
4./GZ option: This option will do the following (1) initialize the memory and variables. This includes initializing all automatic variables in 0xCC, 0xCD (cleareddata) initializing the memory allocated in the heap (that is, dynamically allocated memory, such as new), 0xD
D (Deaddata) fills the heap memory that has been freed (for example, delete), beginning at 0xFD (defencdedata)
To start a protected memory (the debug version adds protected memory before and after dynamically allocating memory to prevent cross-border access), its
The words in brackets are Microsoft's suggested mnemonics. The advantage of this is that these values are very large and as pointers are not possible
(and pointers in 32-bit systems are rarely odd numbers, and in some systems odd pointers can produce run-time errors),
Are rarely encountered as numeric values and are easily recognizable, so it is advantageous to find the re in the Debug edition
Lease version of the error encountered. The special note is that many people think that the compiler will initialize variables with 0来, which
Is wrong (and this is bad for finding errors). (2) when calling a function through a function pointer, it passes through the check stack
The pointer verifies the match of a function call. (Prevent prototype mismatch) (3) function to check the stack pointer before returning to confirm that it has not been
Modify. (Prevent Cross-border access and prototype mismatch, together with the second item can be roughly simulated frame pointer omitted FPO)
Usually the/GZ option causes the debug version to go wrong and the release version is normal because the release version is not in the beginning
The initialization variable is random, which may cause the pointer to point to a valid address and hide the illegal access. Besides
/GM/GF and other options cause fewer errors, and their effects are obvious and relatively easy to spot. Three
How to "Debug" release version of the program encountered debug success but failed release, obviously is a very frustrating
, and often do not have the problem. If you look at the above analysis, combined with the specific performance of the error, quickly find the wrong
Mistake, is very good. But if you can't find out for a while, here are some strategies for this situation. 1. The front has
As mentioned, debug and release are just the differences between a set of compilation options, and there is virtually no definition to distinguish between them.
We can modify the release version of the compilation options to narrow the error range. As mentioned above, you can select the release
Item by note: That article is over, as if there were some.
In VC when the whole project is large, the software is often in the debug state can run in the release state is unable to run the situation. Since developers usually develop software in debug state, this is often done after two months of hard work and confidently preparing to release the software. In order to avoid unnecessary losses, we'd better conduct the following checks:
1, often test the two versions of software.
2, do not easily attribute the problem to the debug/release problem, unless you have fully tested the two versions.
3, pretreatment of different, also may cause such problems. One possibility of a problem is that different preprocessing tokens are defined between different versions of the compilation. Please try the following changes to your debug version of the software: in the Pro
Jectsetting (category) is set as "General" in the C + + entry in Alt-f7, and changes "_de
BUG "is defined as" Ndebug ". Set the directory to" preprocessor "and add the definition" _DEBUG to "undefinedsy
Mbols the input box. Select Rebuildall and recompile. If a compiled program has caused a problem, check the code
Make the following changes: Change assert () to verify (). Find the code defined in "#ifdef_DEBUG", such as
The code needs to be moved to the definition outside of the release version. Find Trace (...) In the code, because this
Some of the code is not compiled in release. So please check carefully if the code that you need in release is not
Be cheap.
4, variable initialization brings about the difference, in different systems, or in the debug/release version of the differences exist, so please initialize the variable.
5. Do you already have a warning at compile time? Set the warning level to 3 or 4, and then ensure that no warnings appear at compile time.
6. Whether or not to change the resource file.
7, in addition to release version of the software can also be debugged, please make the following changes: In "Projectsettings" in the "C++/C" project under the Set "category" as "General" and the "Debuginfo" set to " Programdatabase ". Select the Generatedebuginfo check box under the Link project. The "Rebuildall" approach would produce
Some of the limitations: The value of a variable in Mfcdll cannot be obtained. All DLL works that are used by the software must be
Make changes. Another: Msbug:ms's technical documentation shows that in VC5 for DLL "Maximizespee
The D "Optimization option is not fully supported, so this can cause memory errors and cause the program to crash.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.