Discussion on the difference between DEBUG and RELEASE (Z)

xiaoxiao2021-03-06  41

I often see someone in 9CBS asking that Debug is working proper but Release failure. Previous discussion is often

Experience, did not point out what the real cause of this will, if you want to find true reasons, you usually have to be lucky. most

I have seen some books in this area, refer to some post on 9CBS, and then study the two

s difference. The following is some of my experience, which is used to share with you.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

This article mainly includes the following:

1. The essential difference between Debug and Release compilation

2. What is the event?

2. How to "debug" Release version of the program

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Discussion on the essence of Debug and Release

First, Debug and RELEASE

The essence of compilation methods DEBUG is often referred to as a debug version, which contains debugging information, and does not make an optimization, easy programmer

Debugger. Release is called a release version, it is often a variety of optimization, making the program in code size and transport

It is best to use it very well. DEBUG and Release True Secrets in a group

Compile option. The following is listed below (otherwise additional, other than that, other, such as / fd / fo, but

The difference is not important, usually they don't cause the Release version of the error, not discuss this) Debug version: / md

D / MLD or / MTD uses Debug Runtime Library (debug version runtime function library) / OD close

Chemical switch / D "_debug" is equivalent to #define _debug, open the compile debug code switch (mainly for the ASSERT letter

Number / zi Create Edit and Continue Database, so if the source is modified in debugging

Code does not require recompilation / GZ help capture memory error / GM to open minimized heavy link switch, reduce link time

Release version: / md / ml or / mt uses a release version of the runtime function library / O1 or / O2 optimized switch

Make the smallest or fastest / D "ndebug" close condition to compile the debug code switch (ie, the Assert function) / g

F combined with repeated strings and put the string constants in read-only memory to prevent modifications, debug and r

Elease has no nature of the boundary, they are just a set of compile options, the compiler is just in the scheduled row

move. In fact, we can even modify these options to get an optimized debug version or a tracking statement.

release version.

Second, where the release version is wrong

With the above introduction, let's take a look at these options to see how the Release version is generated.

1. Runtime Library: Which runtime library is usually only impact on the performance of the program. The debug version of Runtime Library contains debugging information and has some protection mechanism to help find errors, so performance is not as good as release. The Runtime Library provided by the compiler is usually very stable and will not cause the Release version of the error; It should be pointed out that if Debug is wrong, even if Release is normal, the program is definitely a bug, but it may be that the release version of the RELASE version is not expressed. 2. Optimization: This is the main reason for errors, because the source program is basically directly translated, while the compiler will make a series of assumptions after opening optimization. Such errors have the following: (1) Frame Pointer omit (referlateral): In the function call, all call information (return addresses, parameters), and automatic variables are placed in the stack. If the declaration of the function is different (parameters, return value, call mode), an error is generated --- but DEBUG mode, the stack is implemented through the address saved by the EBP register, and if there is no error, the error occurred (Or the crossover "not much"), the function can usually be implemented properly; Under the Release mode, the optimization will omit the EBP stack base pointer, so through a global

The pointer access stack will cause the return address error that the program crashes. Strong type of C can check most such

Error, but if you use ambiguous type conversion, it will not. You can force join / y-edit in the Release version

The translation will turn off the frame pointer to determine whether such errors are. Such errors are usually: ● MFC Message Response Letter

Number written errors. Correct AFX_MSG LRESULT OnMessageown (WPARAM WPARAM, LPARAM LPAR

AM); ON_MESSAGE macro contains mandatory type conversion. One of the methods to prevent this error is to redefine on_message

Macro, add the following code to stdafx.h (after #include "afxwin.h"), compilation when the function is wrong

Will report an error #undef on_Message #define ON_MESSAGE (Message, MemberfxN) / {Message, 0

, 0, 0, AFXSIG_LWL, / (AFX_PMSG) (static_cast

/ CWnd :: *) (WPARAM, LPARAM)> (& Memberfxn)} (2) Volatile Type Variable: Volatile

The compiler This variable may be modified in an unknown manner outside the program (such as the system, other processes, and threads). Optimizer

In order to improve program performance, some variables are often placed in registers (similar to the register keyword), while others

The process can only modify the memory where the variable is located, and the value in the register has not changed. If your program is multi-threaded

Or you find that the value of a variable does not match the expected, you are confident that it is set, it is likely to meet this.

problem. This error sometimes manifests the program to optimize the normal optimization in the fastest optimization. Tell the suspicious variable

Plus Volatile try. (3) Variable Optimization: The optimization procedure optimizes variables according to the use of variables. For example, there is an unused variable in the function, which is likely to cover an array of offers in the Debug version, and in Releas

E version, this variable is likely to be optimized, and the array crosstation will destroy the data used in the stack. Of course, actual

The situation will be much more complicated than this. There are errors related to this: ● illegal access, including array offline, pointer error, etc.

For example Void fn (void) {INT i; i = 1; int A [4]; {INT J; j = 1;} a [-1] = 1; // of course

The error will not be so obvious, such as the subscript is the variable A [4] = 1;} J Although the scope is out of the array,

Its space has not been retracted, so I and J will cover the offline. And Release version is not very role due to I, J

It may be optimized so that the stack is destroyed.

3. _debug and ndebug: When _debug is defined, the assert () function is compiled, while NDebug is not compiled. In addition, there is a series of assertion macros in VC . These include: ANSI C assertion void assert (int expression); C Runtime Lib assertion _ASSERT (booleanExpression); _ASSERTE (booleanExpression); MFC assert ASSERT (booleanExpression); VERIFY (booleanExpression); ASSERT_VALID (pObject); ASSERT_KINDOF (classname, pobject ); ATL asserts Atlassert (BooleaneXpression); in addition, the compilation of the trace () macro is also controlled by _debug. All of these assertions are only compiled in the Debug version, and it is ignored in the release version. The only exception is verify (). In fact, these macros are calling the assert () function, but there are only some debugging code related to the library. If you add any program code in these macros, not just Boolean expression (such as assigning, you can change the variable value of the variable value), then the Release version does not perform these operations, resulting in an error. Beginners are easy to make such mistakes, the method of finding is also very simple, because these macros have been listed above, as long as the VC Find in Files feature is used to find these macros in all files, then check can. In addition, some masters may also join the criteria compilation of #ifdef _debug, too

Pay attention to it. By the way, it is worth it is verify () macro, this macro allows you to put the program code in Boolean expression

in. This macro is usually used to check the return value of the Windows API. Some people may abuse this for this reason.

(), In fact, this is dangerous, because verify () violates the idea of ​​asserting, can't make the program code and debug code

Completely separated, eventually can eventually bring a lot of trouble. Therefore, experts recommend that this macro is used as much as possible.

4. / GZ option: This option will do these things (1) initialize memory and variables. Including all auto variables, 0xCD (Cleared Data) initialization stacks (ie, dynamically assigned memory, such as new), 0xD

D (DEAD DATA) fills the released heap memory (such as delete), 0xFD (Defencde Data) initialized the protected memory (DEBUG version of the Dynamically assigned memory before and after adding protection memory to prevent offshore access),

The words in the middle brackets are the help notes recommended by Microsoft. The benefits of this is that these values ​​are very large, and it is impossible as a pointer.

(And 32-bit system pointers are rarely odd, in some systems, odd pointers in the system generate runtime errors),

As a value, it is very few, and these values ​​are also easy to identify, so this is also very beneficial to find RE in Debug.

The error will be encountered by Lease. It is important to note that many people think that the compiler will use 0 to initialize the variable, this

Yes wrong (and this is very disadvantage). (2) When the function is called by the function, it will be checked.

Pointer verification function call matching. (Preventing Original Matching) (3) The function returns the front inspection stack pointer, confirmed that it is not

modify. (Prevent off -ral access and original formation, with the second item, can generally simulate the frame pointer omitted FPO)

Typically / GZ options will cause the debug version to go wrong and the normal phenomenon of the Release version, because the release version is not

The variable that is initiated is random, which is likely to make the pointer to a valid address to mask illegal access. In addition,

/ GM / GF options have less cases, and their effect is obvious, it is easier to find. three,

How to "debug" Release version of the program encountered Debug success but Release failed, it is obviously a very frustrated

Things, and often there is no way. If you look at the above analysis, combine the specific performance of the mistake, soon find the wrong

Mistaken, although very good. But if you can't find it for a while, some strategies in this case will be given. Previously

It is mentioned that Debug and Release are only the difference in compilation options, and there is no definition that can distinguish between them.

We can modify the Release version of the compilation option to narrow the range of error. As mentioned above, you can choose Release

The items are noted: that article is over, it seems to have some no [EM01]

When the entire project is large in the VC, the software often runs in the debug state and cannot run in the Release state. Since developers usually develop software in the Debug state, this situation often occurs after we have worked hard for more than one month, and the preparation of confidence will happen when the software is issued. In order to avoid unnecessary losses, we should do the following exams:

1. Two versions of the time test software.

2, do not easily return the problem into debug / release problem unless you have fully tested two versions.

3. Different pretreatment, it is also possible to cause such problems. One possibility of a problem is to define different preprocessing tags between different versions of compilation. Please try the following changes to your debug version of the software: in "Pro

Setting the directory (category) in the C / C item in JECT SETTING (ALT-F7) "," General ", and change" _de

"Is defined as" nDebug ". Set the directory as" preducessor "and add definition" _debug to "undefined Sy

Mbols "Input Box. Select Rebuild All to recompile. If you have a compiled program, please

Perform as follows: Change assert () to verify (). Find the code defined in "#ifDef _debug", if you need these code in the Release version, please move them to the definition. Find Trace (...) in China, because this

Some code is not compiled in Release. So please carefully check if the code you need in Release is not

It is cheap.

4, the difference in the initialization of variables, there is such differences between different systems, or between Debug / Release versions, so please initialize variables.

5, is there a warning when compiling? Set the warning level to 3 or 4, and then ensure that there is no warning when compiling.

6. Is there a resource file?

7. In addition, the software can also be commissioned for the Release version, please do the following to the "CATEGORY" to "C / C" under "Project Settings" and set "Debug Info" to "Program Database" ". In the" LINK "project, select the" Generate Debug Info "check box. "Rebuild All" will be produced

Some restrictions: The value of variables in the MFC DLL cannot be obtained. All DLL projects that must be used for this software

Change. Another: MS BUG: A technical document of MS shows that in VC5 for DLL "Maximize Spee

d "Optimization options are not fully supported, so this will cause memory errors and cause the program to crash.

转载请注明原文地址:https://www.9cbs.com/read-78799.html

New Post(0)