1 Case Description
As a Windows programmer, the most worrying thing to see is that the program crashes (abnormally), and Windows prompts the program to perform an illegal operation that is about to close. Please contact your vendor. Oh, this word of Microsoft's "famous", I am afraid programmers are most afraid to see the most common things.
During the testing of a large software, the initial program crash seemed inevitable. In fact, the program crashes in the test is not scary, but the success of the test. As a development we need to be concerned about which function or line in the program has caused the system to crash, so that it can be targeted to correct.
This article describes some of the methods of locating crashes that I have summarized.
2 case study
Here are a few of the common crashes and their corresponding treatments:
1. A program that crashes on the release version and crashes on the debug version.
Solution: Remove all breakpoints, run the program directly on the debug version, when the program crashes, the VC will automatically jump to locate the crash code line, this method is the simplest and most commonly used.
2. For programs that do not crash on the debug version but the release version crashes, there is a good chance that the debug and release versions are different. For example, all members of the debug version will be cleared at the time of construction 0, while the release version of all members at the time of construction is the original value of memory, and debug has run-time library for protection, which will cause some programs in debug normal and release crashes.
Solution:1) in the program to print, through the program crashes before the print positioning error location, 2) Paragraph by comment Code, until the program does not crash. This method takes a long time, requires a high level of programmer requirements, and is difficult to deal with in situations where a bug that is not necessarily a requirement or that is difficult to build an execution environment.
3. For the customer at the scene of the crash, obviously not suitable for directly with a computer to debug.
Solution: There should be a file to record the crash information, customer service personnel can send the crash information file to the programmer, so that the programmer to query the cause of the crash, and then use the compile time to generate a map file (project information files, stored in the version of the compiler) information to locate the problem function or problem code line. Here's a discussion of this approach:
3 resolution process
The third situation in the previous section is also the most difficult to resolve, and the process is as follows:
1. Crash callback registration, block Windows program crashes;
2. In callback processing, the output crashes the cause, crashes the memory address, crashes the stack;
3. Project output map file;
4. Locate the crash function by crashing the memory address and the map file.
5. Use cod files to pinpoint crash lines
3.1 Crash callback registration
In fact, the amount of information provided by the Windows-only Error message dialog box is very limited. Registering a custom error handling callback function with SetUnhandledExceptionFilter, you can replace the WIN32 default exception handling filter (top-level exception filter), and you can print out the crash stack, This is useful for locating crash reasons.
Function prototypes for SetUnhandledExceptionFilter:
Lptop_level_exception_filter SetUnhandledExceptionFilter ( Lptop_level_exception_filter lptoplevelexceptionfilter); |
function: register and unregister exception handling callback;
usage: First call to register exception handling callback, second call logoff;
return value : Returns the current exception filter. You need to save this function pointer and call SetUnhandledExceptionFilter again as a parameter when you unregister the exception handling callback. This value is also required for printing exception handling.
parameters: callback function for exception handling;
3.2 output crash information
The crash information is printed in the exception callback function and output to the file under the program execution directory:
The function prototype of the exception handling callback:
LONG WINAPI callbackdebuginfo (exception_pointers *pexception); |
function: exception handling callback processing, print crash information;
usage: Register custom error handling callback: SetUnhandledExceptionFilter (Callbackdebuginfo);
return value : The exception_continue_execution– error has been fixed and continues execution from the point where the exception occurred
exception_continue_search– continue to find exception filters
exception_execute_handler– Normal return
parameters: crash information structure, including crash reason, crash module, crash address, crash stack, etc.;
Common causes of crashes are:
Exception_access_violation = c0000005h read/write memory error
Exception_int_divide_by_zero = c0000094h except 0 error
Exception_stack_overflow = C00000FDH Stack overflow or out of bounds
Exception_guard_page = 80000001h Property page conflict created by Virtual Alloc
Exception_noncontinuable_exception = c0000025h Non-persistent exception, program cannot resume execution, exception handling routine should not handle this exception
Exception_invalid_disposition = c0000026h code used by the system during exception handling
Exception_breakpoint = interrupt at 80000003h Debug (INT 3)
Exception_single_step = 80000004h Single-Step debug state (INT 1)
3.3 Output Map File
Map file Logger global symbols, source files and code line number information, is the entire program engineering information static text. You can open a map file with a text reading tool such as Ultra Edit or Notepad.
In VC, open the Project Settings Options page, select the C + + tab, and in the bottom Project options, enter:/zd, and then select the Link tab and select the Generate mapfile check box. In the bottom of the Project Options, enter:/mapinfo:lines, which indicates that the row information is added when the map file is generated.
Finally compile the map file can be generated, in the debug or release directory of the project to find the map file just generated, the file name is "project name. Map".
3.4 Use Map file to find the crash function
With the above steps, we've got the MAP file, so how do we use it? The following step shows the process of using the map file to locate the program crash line.
1. We first add the code to the code for the illegal memory operation (the most common exception):
BOOL Cmainframedlg::oninitdialog () { :: SetProp (M_hwnd,afxgetapp ()->m_pszexename, (HANDLE) 1); S32 *p=null; *p= 123; |
2. Execute the program, the program at the beginning of the exception, in the exception print file print the following information:
======================== Crash Information ========================== Crash time: 2009/06/02 16:58:22 Crash reason: illegal memory operation Exception code = c0000005 Exception address = 0x0045a76f Exception module: E:\ccroot\liuxiaojing_Enterprise\Enterprise_VOB\70-nms1\pcmt2\prj_win32\Release\pcmt2.exe Section name:. Text-offset (RVA): 0x0005976f ----------------------Trips of Stack---------------------- E:\ccroot\liuxiaojing_Enterprise\Enterprise_VOB\70-nms1\pcmt2\prj_win32\Release\pcmt2.exe Name:pcmtver-location:2bef |
3. Determine the crash address is: 0x0005976f, locate the function in the map file:
0001:00059420 [email Protected]@@[email protected]@@z 0045a420 f mainframedlg.obj 0001:00059460 [email protected]@ @AAEXXZ 0045a460 f mainframedlg.obj 0001:00059700 [email protected]@@[email protected] 0045a700 f Mainframedlg.obj 0001:00059730 [email protected]@@ Maehxz 0045a730 f mainframedlg.obj 0001:00059a10 [Email protected]@@[email protected] 0045aa10 f mainframedlg.obj 0001:00059c20 [email protected]@ @IAEXXZ 0045ac20 f mainframedlg.obj |
According to 00059730< 0005976f < 00059A10, it is determined that a line in the OnInitDialog function of the CMAINFRAMEDLG produces an exception.
3.5 Use Map code line locating crash line interval
line numbers for. \ Release\mainframedlg.obj (E:\ccroot\liuxiaojing_Enterprise\Enterprise_VOB\70-nms1\pcmt2\source\MainFrameDlg.cpp ) segment. Text 498 0001:00059647 499 0001:00059667 501 0001:0005966e 502 0001:000596AF 503 0001:000596ed 506 0001:00059700 507 0001:00059703 508 0001:00059708 510 0001:0005970f 511 0001:00059720 0001:00059723 515 0001:00059730 516 0001:0005974e 521 0001:0005976d 524 0001:0005977e 526 0001:0005978b |
We find in the code line information of the map file no more than the calculated result 0x0005976f, but we can find the nearest number. Found in the MainFrameDlg.cpp file: 521 0001:0005976d, and the actual crash line in 519 (comment lines and empty lines are also counted), very close to the actual crash line, considering that the program actually executes the assembly instructions, we can in (516 ~524) Find the actual crash line within the line interval.
How to locate program crashes in release version---Use the map file to block Windows crash functions