Bytes ------------------------------------------------------------------------------------------------------------------------
[Technology] how to locate the code location that causes crash
Verycd-fengwen sent to the verycd donkey Software Development Team (http://www.VeryCD.com/groups/Emuledev/), reprinted please indicate the source
Bytes ------------------------------------------------------------------------------------------------------------------------
1. Locate the crash error in the Development Environment
1.1 common crash
1.2 crash
1.3 Note the VC output log
2. Locate the crash error of the released version
3. Tips
3.1 locate the Code Location Based on the program address
3.2 view the corresponding Windows message based on the message Value
3.3 view getlasterror return values
3.4 pause the program in the code
4. Small programming warning
4.1 Use the isbadptr series functions with caution
4.2 Use catch (...) with caution (...)
5. Appendix
5.1 why is the call stack messy during program crash?
5.2 use debugging tools for Windows to view the. dmp file (Error Report)
Bytes ------------------------------------------------------------------------------------------------------------------------
1. Locate the crash error in the Development Environment
1.1 common crash
Let's take a look at the most common crash
See Figure 1(c01.png)
When you run the above program in debug mode, the above box will pop up. VC helps you locate the error. Is a zero-pointer operation. It's very simple, isn't it.
1.2 crash
The hard-to-locate crash is often caused by memory errors (see 5.1 why the call stack is messy when the program crash ). For example, the following code:
Code
Char * P = new char [16];
P [10] = 0xfd;
Delete [] P;
Printf (P );
The preceding Code has two errors: one is that the memory write of 2nd rows is out of bounds, and the other is that 4th rows use the deleted pointer.
However, no error is reported for the above Code in the release and debug of VC. This makes it difficult to locate such errors.
You can use the finalcheck mode of the boundschecker tool to detect this type of problem (see this article for instructions)
After boundschecker is used for detection, two errors can be obtained: Write overrun (write out-of-bounds) and dangling pointer (use the deleted pointer), both of which are precisely located at the error location. Is a good tool.
See Figure 2(c02.png)
See Figure 3 (c03.png)
1.3 Note the VC output log
Boundschekcer sometimes fails to work due to unknown reasons (it may be a program error that is too serious or a bug in boundschecker itself.
Here, VC output logs sometimes provide some useful information.
In the hard-to-find crash, a large part references invalid pointers.
Sometimes the information similar to this can be seen in the VC output log
The most likely exception at 0x004277b7 in “emule.exe is 0xc0000005: Access conflict at the read position 0xfeeeff62 ."
This is very important when boundschecker is not supported. It means to operate on the pointer with a value of 0xfeeeff62 at "0x004277b7.
(For details about how to find the corresponding code line through "program address 0x004277b7", refer to 3.1 ,)
The importance of this information is that this operation will only trigger a warning, but will not cause a crash. When a crash actually occurs, it is likely that it will not be near 0x004277b7,
Even the call Stack has been written in disorder, making it impossible for you to start. (See 5.1 why the call stack is messy when the program crash)
2. Locate the crash error of the released version
The released software crash is often difficult to debug, so many software currently have the "send Error Report" function.
This function can be implemented in the following steps:
A. Use the setunhandledexceptionfilter Function
You can use setunhandledexceptionfilter to set the highest-level exception handling function. When a program encounters any unprocessed exception, it will trigger the function you set. For more information, see msdn and eMule source code.
B. Use the minidumpwritedump Function
In your exception handling function, use minidumpwritedump to save the error information to a file in a specific format. For more information, see msdn and eMule source code.
C. Send an error report
Select a form to send the error report (. dmp) file generated in step 2 to your specified location.
D. View error reports
Here we will introduce how to use VC to view the error report. You can also use the Windows debug tools tool. For the method, see 5.2 use Windows debug tools to view the. dmp file (Error Report)
To view the error report, you need to compile the release code and the. PDB files of the releaseversion. (Both files are in the compiled output directory .) Therefore, when the program is released, the two files must be retained.
Run the. dmp (error report file),. PDB,. EXE. Code in the same directory and use VC to open the. dmp file.
When you press F5 to run the program, it is in the crash state and can be analyzed accordingly.
One note: if the "send Error Report" function is not available or the function is invalid, the "send Error Report" dialog box appears in windows. At this time, there is actually an error report, generally in C: Documents and Settings username local settingstemp A. dmp file (usually only one. dmp)
3. Tips
3.1 locate the Code Location Based on the program address
Follow these steps:
A. Stop the program. (For example, when the program is running, press CTRL + ALT + break in VC, or set a breakpoint to stop the program)
B. Switch to the assembly status. (CTRL + F11)
C. Enter the program address in the address bar and press Enter.
D. You can press Ctrl + F11 to switch back to the code mode.
3.2 view the corresponding Windows message based on the message Value
Enter "message value, WM" in the VC monitoring window to view the corresponding message.
3.3 view getlasterror return values
Enter "@ err, HR" in the VC monitoring window to see lasterror and its explanation.
3.4 pause the program in the code
In the debug version, you can add "afxdebugbreak ();" in the code to pause the program. The release version can use "_ asm int 3 ;"
4. Small programming warning
4.1 Use the isbadptr series functions with caution
When using a series of functions, such as isbadreadptr, isbadwriteptr, and isbadcodeptr, note that these functions may not be able to achieve your intended purpose.
For example, in the following code, both return false.
Code
Char * P = new char [10];
Bool B;
B = isbadreadptr (p + 10, 1 );
Delete [] P;
Char * q = new char [10];
B = isbadreadptr (P, 1 );
Therefore, do not use the isbadptr function in the program to determine whether the pointer can be operated. These functions can only be used during debugging, or you know exactly what the return values of these functions mean.
4.2 Use catch (...) with caution (...)
To prevent the program crash or solve a crash that you don't understand, you can easily think of a try {} catch (...) {} to solve the problem.
It is true that most of the time there will be no problem, but this try-catch is likely to hide the error in the try, and when this error causes other errors, it is difficult to track this problem.
We recommend that you use catch (...) as few as possible. If you know that a piece of code throws an exception, you should use the exact method. For example, catch (cfileexception * E) and catch (int e.
5. Appendix
5.1 why is the call stack messy during program crash?
When the memory is written in disorder, the program may have crash that is difficult to locate. For example, the call Stack may be messy, or it may go into non-existent code. Here is an example
Code
Class ca
{
Public:
CA (){}
~ CA (){}
Virtual F (){}
};
Void show ()
{
Printf ("shown ");
}
Int main ()
{
// The object is created and deleted.
Ca * P = new CA;
Delete P;
// Some normal operations
Int * q = new int;
Int codeaddress = (INT) show;
* Q = (INT) & codeaddress;
// Call the deleted object. The program may be executed anywhere.
P-> F ();
}
The result of the above Code goes to show () and shows show (this is related to the compiling environment, and the test result under vc2003 is like this ). If you understand the vtable mechanism of c ++, you will understand what is going on.
It doesn't matter if you don't understand it. I will give you a rough idea below.
First, the Ca object is created and deleted. If you call p-> F () at this time, most of them will be crash.
The second piece of code can be regarded as some normal operations. A new Q is added, and some values are assigned to it.
If you do not understand the vtable mechanism, you only need to know the "P-> F (); will execute the address indicated by the variable where Q points to the variable. (There is no typo here, which is two "variables pointed ")
Here I "kindly" assigned this value a valid function address show. However, in the actual program, the variable that Q points to may be any value, and the variable that it points to is even more of any value.
The program does not know where to go. If this value is too outrageous, you are lucky. The program will crash immediately, and you will know where the error is. But it is annoying that it may be a legal address, so the program will continue,
But sooner or later it will crash, and the call stack will not be fully visible (the reason involves the issue of "derivation of the call stack", which is not mentioned here ),
At that time, it was impossible to know that the deleted P object was called.
5.2 use debugging tools for Windows to view the. dmp file (Error Report)
A. Prepare the code, EXE file, and PDB file corresponding to the Program (in the compilation output directory)
B. Install windbg
C. In windbg, set the symbol in the .pdb directory, the image in the directory where .exe is located, and the code directory to the Code directory.
D. Open the. dmp file.
E. Enter the command. ecxr. (This command returns the environment to the state of crash)
F. Open the call stack (Alt + F6) to view the location of the crash.
G. Analyze
This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/wzwind/archive/2009/11/24/4865196.aspx