Debugging art-Summary of debugging skills

Source: Internet
Author: User

Debugging art-Summary of debugging skills

(This article is pasted from the prepared wiki, and the format is slightly messy without affecting READING)


Q + indicates the question, and a + indicates the answer. Organize in this way. Unless otherwise stated, these skills are applicable to Visual Studio 2003

As a logic program, I can only give a glimpse of assembly-level problems. The content is only for reference. I hope that I can point out the rigor of the statement in order to correct it. However, most of the information is confirmed by experience or reference materials. If you have any questions, please contact me.

 

Q1: Can I debug the release version?

A1: The difference between the release version and the debug version. As far as I know, there are three differences: whether the compilation is "compiler optimized"; whether there is complete debugging information; _ debug macro and ndebug macro;
First, the positions of the three options are as follows:

"Compiler Optimization", in vs2003, is located in the Project Properties (right-click a project on the Solution Explorer panel)-> C/C ++-> Optimization-> the first optimization. Generally, the debug version is set to disabled, and the release version is set to full optimization.
"Whether debugging information exists", in vs2003, is located in project properties-> C/C ++-> General-> debug infomation format. The default release version is disabled, and the debug version uses the most complete program database for edit & continue.
_ Debug macro and ndebug macro, in vs2003, are located in project properties-> C/C ++-> preprocesser definitions. The release version is generally set to ndebug, And the debug version is set to _ debug "Compiler Optimization", which means that the compiler is not translated into assembly line by line according to the source code during compilation, instead, we make changes to the Code for efficiency, such as eliminating unnecessary local variables and removing code that is completely unaffected. Modern compilers have developed very well. They can even adjust the loop order, introduce the statements in the loop to the outside of the loop, and eliminate function calls, it is the most efficient way to ensure that the results are completely consistent.
It is worth noting that:1. the more advanced the compiler, the more powerful the optimization function, the great difference between vs2010 and vs2003. You can write some simple algorithms and then look at the assembly results. 2. even for "experts", the Code optimized by the compiler is often better than the code optimized manually (because the compiler is written to the optimization experts), so when writing code, we should pay more attention to the algorithm and function call structure issues, and do not have to pay too much attention to details such as local variables. The compiler will do a good job in local problems.

So some people found that the execution order was very strange when debugging with release, and the source code was not correct, which was actually caused by Compiler optimization. "Whether debugging information exists" determines whether the PDB file is complete. The PDB file must record both the source code location for tracking and some additional address information, to display the value of the exit variable. Sometimes you cannot see the value of the variable when debugging the release version. Either the variable has been optimized or the debugging information is incomplete.
_ Debug macro and ndebug macro. This is relatively simple. during compilation, a macro # DEFINE _ debug is automatically defined in the debug version. Therefore, some code only needs to take effect in the debug version.
   # Ifdef _ debug
   // The Code Compiled by the debug Edition
  # Else
   // Code required by release
  # Endif
In this way, the goal can be achieved. The most common is the assert macro. Assert is very common in bottom-Layer Code. The assert function is executed only in debug and is ignored in release. So it is a good thing to test during development. If you need to use assert for the release version, modify the VC settings and change the ndebug macro to _ Debug. However, such modifications may affect other code. (In addition, I have not figured out why the local variables of the debug version are initialized to 0, but the release version is not initialized. Which option is used to control the local variables .) The significance of debugging release is that some bugs can only be reproduced in the release mode, so it is very important to understand the difference between release and debug and modify the settings properly.



Q2: I do not know where to output the debugging information.

A2: the console program can easily output information through printf or STD: cout, But windows Windows programs are troublesome. When writing Windows Gadgets, you can use MessageBox to output information, but it is too inappropriate for large games such as Xunxian.
Logs can be output.
Most of the logic-layer modules can use the Log Module. We recommend that you debug multiple output logs. To view log files, you must use a tool such as ultraedit, notepad ++, and VIM that can automatically detect file changes and re-open the log file so that you can view the output at any time, using notepad may cause you trouble. Logs cannot be output. Use outputdebugstring
The underlying module cannot output logs. If you want to output logs, modifying the source code is too cumbersome. At this time, there is also a trick: the windows. h header file provides a function for output information: outputdebugstring (including two, outputdebugstringa and outputdebugstringw, supporting multibyte and widechar respectively ). For use, you only need to include windows. h In the CPP file you need to debug, And Then assemble the string and output it yourself.

View output results of outputdebugstring. Where is the output of outputdebugstring? The answer is "system debugging information". If you use VC to debug the program, you can see it in the output window. How can I see it without debugging? The answer is to use the "debugview" tool. You can search for it on the internet or ask someone else.

Outputdebugstring is invalid. Windows. H files are too large, which may cause conflicts with source files... Only specific problems can be solved. There are always more problems than methods (quotes from hero ). The reason for not using the debugger is that the debugger may not be powerful at critical moments, especially when the memory has been written incorrectly. It is not a good thing to rely too much on the debugger.

 


Q3: I am debugging the core dump file. The program version is release. The Code has been optimized, the variable values are invisible, and the execution sequence is unclear. I can only see the assembly code. What should I do?

A3: in this case, if you don't want to (can't) give up, just look at the assembly code!
If the luck is not too bad, the source code can correspond to the core dump file, vs2003 can open the hybrid view of assembly and C ++, you can check against. 1. The crash is basically an inaccessible address. So ...... An error occurred while checking which address to access. How can I calculate the value of this address.
2. Analyze the correspondence between each c ++ code and the assembly code. In particular, the IF, for, and while statements in the Assembly must eventually show as a jump (JMP, JNE, and so on), so I understood the jump and understood the execution process. You can also locate function calls.
3. If it is found that C ++ and assembly are not easily matched, do not be alarmed. It is likely that optimization has caused some functions to be expanded. After optimization, analyze and analyze the functions.
Very effective method: Find someone who is similar to you or knows Assembly better than you, and study it together. You can broaden your thinking and encourage each other.

 


Q4: What if the breakpoint is too late? What should I do if the breakpoint cannot be broken down?

A4: I used to think that if I have code and want to use a breakpoint, it can always be broken down. It is impossible to use attach to debug the program after I start the program. However, it turns out that if the programmer has n ways to debug the program, nature has N2 ways to tease the programmer. For example:
1. The program logic is closely related to the system time. For example, if the cooldown time of debugging cooldown is only one second, it will take two seconds for you to break down the breakpoint. You may not always be able to enter the logical branch you want to enter. For example, at the network layer, the debugging time is very limited, and it takes 5 seconds to time out.
2. If the operating system is exhausted, it cannot be broken down.
3. The error occurs when the program is started. If it is started from vs2003, no error occurs. If it is not started from vs2003, an error occurs. However, it is too late for you to start the program and attach it again, because it takes only half a second from startup to error.
4. The probability of error re-occurrence is extremely low. The re-occurrence occurs once a dozen times, and it is more difficult to re-create the program directly starting from vc2003.
In general, the first two phenomena can still be solved. In the first case, you can change the logic and give yourself more time. In the second case, check the system service and even reinstall vs. There is still a solution. In the third case, I just met this month. The key variable is a random value. (In addition, this phenomenon shows that there are subtle differences in the program memory layout after VS starts the program, directly starts the program, and attach .) In the fourth case, memory access exceeded the limit. The reason is that the operating system sometimes detects an exception and sometimes does not access the invalid memory. There are several ways to list them, but you have to make full use of your talents.

1. Force breakpoint INT 3. Specific practice: Add _ asm int 3 to the Program (if you are using gcc, you can add ASM ("int $3");). The program will crash when it is executed here, then, Windows will ask you if debugging is required, and then you can use vs2003 to debug it with ease. A good way. Try it yourself when writing a tool. Unfortunately, this method is invalid in our project, because this exception will be caught by the underlying layer (jexception: Init (), and then print a bunch of information to exit ...... There is no debugging opportunity.
2. Assert (expression) and outputdebugstring. If you have a rough idea about the problem, for example, "If index is 3 in this place, it will be out of the boundary", add an Assert (Index = 3 ), in debug mode, try again. Also, do not delete assert because it will not run in release mode. Writing meaningful assert is helpful for code robustness.
3. Add an if statement. Add an if sentence and add some meaningless code to the if {}, such as int I = 0; ++ I; and then place the breakpoint on ++ I. It is a common practice, but if you encounter very strange situations, debugging is not easy to reproduce, and the optimization option to disable release is not easy to reproduce, you can only enable optimization, however, optimization will delete your useless code. At this time ...... Use the following while (true); method.
4. while (true); the inconvenience of using assert is that once the Code enters the assert, it is difficult to return to the previous place; it is not easy to use the previous method in the case of optimization. You often want to continue single-step debugging after capturing errors. Therefore, after capturing errors, let the program enter an endless loop, and then the program will get stuck and wait for you to go in and debug it slowly. When Debugging starts, vs2003 can drag the arrow to change the code currently executed and jump out of the endless loop. Or you can use an empty loop for many times, for example, 100000000 times, or some programs can use sleep (10000). The idea is the same.
 

 

Q5: during debugging, check the value of the member variable of the object in watch. However, I feel that the syntax of watch is different from that of C ++. Is there any technique?

A5: I am not using watch very well. Several issues need to be solved with watch:
Debug the STL container. I will only debug the vector. The method for debugging the vector is similar to debugging the C ++ array. For example, there is an array a [10] and 10 values in the monitoring are as follows:
  A [0], 10
Just write it like this, and the vector is similar. Debugging map and list in vs2003 is not very powerful. . Member variables in member variables of the debugging object ......; Because watch does not support "->" well, it cannot be identified by writing a large string of statements. Super brother taught me a trick: When Using quick watch to select a member variable in quick watch, the text in the quick watch input box will also change ...... The original content in the input box is the expression of the variable you want. Stick it to the watch window!
Calling a function in watch may cause a strange crash. Because the watch function call may also encounter exceptions. When debugging a strange crash, you can see if you have written something you shouldn't have written in watch.
 

 

Q6: the client or server is very difficult to understand. I don't know where to start.

A5: if the program speed suddenly becomes very slow and can be reproduced, you can run it and use vs attach to the process, then break all, and try it several times (touch probability ).
Check whether it is stuck in the same place multiple times. If you are stuck in the same place multiple times, you can make a bold guess and experiment. Although this method is silly, the following problems have been solved: 1. the skill system is incorrectly filled in, resulting in a loop of 10000000 ...... Frame; 2. the client is stuck due to a large number of logs running on the external server. As far as I know, these two successful experiences are actually magical.



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.