Differences between debug and release

Source: Internet
Author: User

This article mainly includes the following content:
1. essential differences between debug and release compilation methods
2. under which circumstances will the release version go wrong?
2. How to "debug" release programs
--------------------------------------

Discussion on essential differences between debug and release

I. essential differences between debug and release compilation methods

Debug is usually called a debug version. It contains debugging information without any optimization, so that programmers can debug the program easily.
. Release is called a release version. It is often optimized to make the program run at the code size and speed.
Is optimal, so that users can use it well.
The real secret of debug and release lies in a set of compilation options. The options for the two are listed below.
(Of course there are others, such as/FD/Fo, but the difference is not important. Generally, they do not cause rele.
ASE version error, not discussed here)

Debug version:
/MDD/MLD or/MTD use the debug Runtime Library (the runtime function library of the debug version)
/OD turn off the optimization Switch
/D "_ debug" is equivalent to # DEFINE _ Debug. Enable the compile and debug code switch (mainly
Assert function)
/Zi creates the edit and continue (Edit to continue) database, so that the database has been debugged
If the source code is modified, you do not need to re-compile it.
/GZ helps capture Memory Errors
/GM enables the minimize reconnection switch to reduce the link time

Release Version:
/MD/ml or/MT use the runtime function library of the released version
/O1 or/O2 optimization switch to minimize or minimize the program
/D "ndebug" Disable the Conditional compilation and debugging code switch (that is, do not compile the assert function)
/GF combines repeated strings and puts string constants in read-only memory to prevent
Modified

In fact, there is no essential limit between debug and release. They are just a set of compilation options.
Only follow the predefined options. In fact, we can even modify these options to get optimized calls.
Trial version or release version with tracking statement.

Ii. under which circumstances will the release version go wrong?

With the above introduction, let's compare these options one by one to see how release errors are generated.

1. Runtime Library: Specifies the runtime function library to be linked, which usually only affects the performance of the program. Debug version
The Runtime Library contains debugging information and uses some protection mechanisms to help identify errors.
It is better to release a version. The Runtime Library provided by the compiler is usually stable and will not cause release errors.
Because the debug Runtime Library enhances error detection, such as heap memory allocation
Now debug is wrong but release is normal. It should be noted that if debug is wrong, even if release
Normally, the program must have bugs, but it may be that the release version has not been shown in a certain operation.

2. Optimization: This is the main cause of errors, because the source program is basically translated directly when optimization is disabled.
After optimization, the compiler will make a series of assumptions. There are several types of errors:

(1) frame pointer (frame pointer) omitted (FPO for short): All call information during function call
(Return address, parameters) and automatic variables are all placed in the stack. If the declaration and implementation of a function are different (parameter, return
Back value, call method), it will produce an error ---- but in debug mode, stack access through the EBP register
If there is no array out-of-bounds error (or not many), the function usually can
Normal execution; In the release mode, the optimization will omit the base address pointer of the EBP stack, so that a global pointer is used to access the stack.
The returned address is incorrect because the program crashes. C ++'s strong type feature can check for most of these errors, but for example
If forced type conversion is used, it will not work. You can add the/Oy-compilation option to the release version.
The drop frame pointer is omitted to determine whether such an error occurs. Common Errors include:

● An error occurred while writing the message response function of MFC. Correct should be
Afx_msg lresult onmessageown (wparam, lparam );
On_message macro contains forced type conversion. One way to prevent this error is to redefine on_message.
Macro, add the following code to stdafx. H (after # include "afxwin. H"), compile when the function is incorrect.
An error is reported.
# UNDEF on_message
# Define on_message (message, memberfxn )\
{Message, 0, 0, 0, afxsig_lwl ,\
(Afx_pmsg) (afx_pmsgw) (static_cast <lresult (afx_msg_call \
Cwnd: *) (wparam, lparam)> (& memberfxn )},

(2) Volatile variable: Volatile tells the compiler that the variable may be modified in an unknown way outside of the program.
(Such as systems, other processes, and threads ). To improve program performance, the optimization program usually places some variables in registers.
(Similar to the Register keyword), while other processes can only modify the memory where the variable is located
The value in the tool has not changed. If your program is multi-threaded, or you find that the value of a variable does not match your expectation
If the email has been correctly set, you may encounter such a problem. This kind of error sometimes appears as the program is optimized as quickly as possible
Error while the minimum optimization is normal. Add volatile to the variables you think are suspicious.

(3) Variable Optimization: The optimization program optimizes the variables based on the usage of the variables. For example, one of the functions is not
The variable used in the debug version may mask an array out of bounds. In the release version, this variable
It is likely to be optimized. In this case, the array out of bounds will destroy useful data in the stack. Of course, the actual situation is more complicated than this.
Yes. Related errors include:
● Unauthorized access, including array out-of-bounds and pointer errors. For example
Void FN (void)
{
Int I;
I = 1;
Int A [4];
{
Int J;
J = 1;
}
A [-1] = 1; // Of course the error is not so obvious. For example, the subscript is a variable.
A [4] = 1;
}
J has a scope when the array is out of bounds, but its space is not reclaimed, So I and j will mask
. The release version may be optimized because I and j are not very useful, so that the stack is damaged.

3. _ debug and ndebug: When _ debug is defined, the assert () function will be compiled, while ndebug does not
Compiled. In addition, there are a series of assertion Macros in VC ++. This includes:

Ansi c asserted void assert (INT expression );
C Runtime lib assert (booleanexpression );
_ Asserte (booleanexpression );
MFC assert (booleanexpression );
Verify (booleanexpression );
Assert_valid (pobject );
Assert_kindof (classname, pobject );
ATL assertion atlassert (booleanexpression );
In addition, the compilation of the trace () macro is also controlled by _ debug.

All these assertions are compiled only in the debug version, but are ignored in the release version. The only exception is
Verify (). In fact, these macros call the assert () function, but attach some library-related
Debug the code. If you add any program code to these macros, not just boolean expressions (such as value assignment
Function calls that change the value of the variable), so the release version will not perform these operations, resulting in errors. Chu
It is easy for scholars to make such mistakes, and the search method is very simple, because these macros are listed above, as long as you use v
The find in files function of C ++ finds the place where these macros are used in all files of the project and then checks them one by one. In addition
Some experts may also add Conditional compilation such as # ifdef _ Debug. Pay attention to this.
By the way, it is worth mentioning that the verify () macro allows you to put program code in a Boolean expression. This
Macro checks the return values of Windows APIs. Some may abuse verify () for this reason, fact
This is dangerous because verify () violates the idea of assertions and cannot completely separate the program code from the debugging code.
In the end, it may cause a lot of trouble. Therefore, experts suggest using this macro as little as possible.

4./GZ option: This option will do the following:

(1) initialize memory and variables. Including initializing all automatic variables with 0xcc, 0xcd (cleared data
) Initialize the memory allocated in the heap (that is, the dynamically allocated memory, such as new) and 0xdd (dead data ).
Released heap memory (such as delete), 0xfd (defencde data) initialize protected memory (de
Bug version adds protection memory before and after the Dynamic Allocation of memory to prevent cross-border access), where the word in the brackets is
Comments. The advantage of doing so is that these values are large and it is impossible to act as pointers (and the 32-bit System
The needle is rarely an odd value. In some systems, the odd number pointer produces a running error,
These values are also easy to identify, so it is helpful to find the release version in the debug version.
Error. Note that many people think that the compiler will use 0 to initialize the variable. This is wrong (and it is very
Is not conducive to finding errors ).
(2) When a function is called through the function pointer, the matching of the function call is verified by checking the stack pointer. (Prevent original
Shape mismatch)
(3) Check the stack pointer before the function returns, and confirm that it has not been modified. (Preventing out-of-the-Boundary Access from mismatched with the original form
The combination of items can roughly simulate frame pointer omitting FPO)

The/GZ option usually causes errors in the debug version and the release version is normal, because
Uninitialized variables are random, which may cause the pointer to point to a valid address and mask illegal access.

In addition,/GM/GF and other options cause fewer errors, and their effects are obvious and easier.
Found.

3. How to "debug" release programs

When debugging succeeds but the release fails, it is obviously very frustrating and often cannot be started. For example
If you have read the above analysis and combined with the specific performance of the error, it is good to quickly find the error. However
No, the following provides some strategies in this case.

1. As mentioned above, debug and release are only the differences between a set of compilation options. In fact, there is nothing
The definition can distinguish the two. We can modify the compilation option of release to narrow down the error range. As mentioned above, you can
Change the release options to the corresponding debug options one by one, for example,/MD to/MDD and/O1 to/OD.
Or change the running time to program size optimization. Note that only one option is changed at a time to see which option is incorrect
Errors related to the options are found. These options are available in project \ Settings...
Select directly from the list. Do not manually modify it. Since the above analysis is quite comprehensive, this method is the most
Valid.

2. In the programming process, you should always pay attention to testing the release version, so as to avoid too many final code and a tight schedule.
.

3. Use the/W4 warning level in the debug version to obtain the maximum error information from the compiler,
For example, if (I = 0) will cause/W4 warning. Do not ignore these warnings. This is usually caused by a bug in your program.
. But sometimes/W4 will bring a lot of redundant information, such as unused function parameter warnings, while many message processing functions
Some parameters are ignored. We can use
# Progma warning (Disable: 4702) // disable
//...
# Progma warning (default: 4702) // re-allow
To temporarily disable a warning or use
# Progma warning (push, 3) // set the warning level to/W3
//...
# Progma warning (POP) // reset to/W4
To temporarily change the warning level. Sometimes you can only use/W4 in the code that is considered suspicious.

4. You can debug your release version just like debug. In Project/s
In ettings..., select Settings for "Win32 release", C/C ++, and category.
General, debug info Select Program database. At the end of the link tag project options
Add "/OPT: ref" (do not enter the quotation marks ). In this way, the debugger can use the debugging symbol in the PDB file. However, when debugging
You will find it difficult to set breakpoints and to find variables-these are all optimized. Fortunately, CA
Ll Stack window still works normally, even if the frame pointer is optimized, stack information (especially the return address) can still be found
. This is helpful for locating errors.

Contact Us

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.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.