As mentioned above, the dump file can save the Process status for easy analysis. Because the dump file records the specific information of a process at a certain time point, it is very important to save the dump. For exampleProgramCrash: dump should be obtained when the command that causes the crash is executed (that is, when the 1st chance exception occurs), so that the direct cause of the problem can be seen during dump analysis.
Adplus is a vbs script in the same directory as windbg. Adplus is mainly used to capture dump files. For more information, see the adplus help in the windbg help file. There are some common usage:
Assume that our target program is test.exe:
Run the following command to monitor the time period before test.exerun crashes:
Adplus-crash-PN test.exe-o c: \ dumps |
When test.exe crashes due to 2nd chance exception, adplus generates a full dump file in c: \ dumps. When 1st chance AV exception or 1st st chance breakpoint exception occurs, adplus generates the mini dump file in c: \ dumps.
You can also use:
Adplus-crash-PN test.exe-fullonfirst-o c: \ dumps |
The difference is that after the-fullonfirst parameter is added, the full dump file will be generated for both 1st chance exception and 2nd chance exception.
Assume that the deadlock or memory leak in test.exe is not a crash. To obtain a dump at any time, run the following command:
Adplus-Hang-PN test.exe-o c: \ dumps |
This command immediately captures full dump of test.exe under c: \ dumps.
The more flexible method of adplus is to use the-C parameter to bring the configuration file. In the configuration file, you can select the time when the exception occurred, whether the generated dump is Mini dump or full dump, or set breakpoints. The last chapter introduces the adplus parameter selection principles.
Case study: under what circumstances dr. Watson cannot record dump files
Problem description
The customer claims that the program developed with VC occasionally crashes. To obtain detailed information, the customer activates dr. Watson so that the dump file can be automatically obtained when the program crashes. However, after the problem occurs again, dr. Watson did not record the dump file.
Background
The dump file contains the memory image information. In Windows, dump files are divided into kernel dump and user dump. The former is generally used to analyze issues related to the kernel, such as drivers; the latter is generally used to analyze issues related to user State programs. Unless otherwise stated, the dump mentioned later in this book represents the user-mode dump. User dump is divided into mini dump and full dump. The former is small and only some common information is recorded. The latter records all contents of the user State of the target process. Windows provides the minidumpwritedump API for programs to call to generate mini dump. You can use the debugger and related tools to capture the full dump of the target program. After obtaining dump, you can use the debugger to check dump content, such as call stack, memory, and exception. For more details about dump and debugger, we will introduce it later. Documents related to dr. Watson are:
Description of the dr. Watson for Windows (drwtsn32.exe) Tool Http://support.microsoft.com /? Id = 308538 Specifying the debugger for unhandled user mode exceptions Http://support.microsoft.com /? Id = 121434 Info: choosing the debugger that the system will spawn Http://support.microsoft.com /? Id = 103861 |
That is to say, by setting the AeDebug item in the registry, you can select the debugger for debugging after the program crashes. Select dr. Watson to directly generate the dump file.
Problem Analysis
Back to this issue, the customer has not obtained the dump file, and there are two possibilities:
1. dr. Watson is not working properly.
2. The customer's program did not crash at all, but it just exited normally.
To test, the followingCodeTest for the customer:
Test the above Code. dr. Watson successfully obtained the dump file. That is to say, dr. Watson works normally. It seems that the crash claimed by the customer may not be caused by unhandled exception. The exitprocess may have been called unexpectedly, and the customer mistakenly believes that it is a crash. Therefore, capture information should not be limited to unhandled exception, but should check the reason for process exit.
When the program exits in the windbg debugger, the system will trigger the process Exit message of the debugger. You can capture dump at this time to analyze the cause of process exit.
If you want the customer to start windbg and then start the program with windbg each time, the operation is complicated. It is better to have an automatic method. Windows provides the option to enable a specified program to start with the debugger. After the registry is set, when the set process starts, the system first starts the specified debugger, and then passes the address and command line of the target process as parameters to the debugger, and then the debugger starts the target process for debugging. This option is especially useful when you cannot manually start a program from the debugger. For example, to debug a Windows service program that starts before the user logs on, you must use this method:
How to debug Windows Services Http://support.microsoft.com /? Kbid = 824344
|
Interestingly, many malicious programs use this method to load processes. Many people call this method ifeo hijacking (Image File Execution option hacking ).
In the windbg directory, there is a script named adplus. vbs that can conveniently call windbg to obtain the dump file. You can use this script here:
How to Use adplus to troubleshoot "hangs" and "crashes" Http://support.microsoft.com/kb/286350/EN-US/
|
For more information about the script, see adplus /? .
New practices
Based on the above information, the specific practices are as follows:
1. Create a key with the same name as the problematic program in the Image File Execution options registry of the client machine.
2. Create a sub-Key of the debugger string type under this key.
3. Set debugger = c: \ debuggers \ autodump. bat.
4. Edit the c: \ debuggers \ autodump. BAT file as follows:
Cscript.exe c: \ debuggers \ adplus. vbs-crash-o c: \ dumps-quiet-SC % 1
|
When the program starts, the system automatically runs cscript.exe to execute the adplus. vbs script. Adplus. the-SC parameter of the vbs script specifies the path of the target process to be started (the path is passed as a parameter and system, and % 1 in the BAT file represents this parameter). The-crash parameter indicates that the monitoring process exits, the-O parameter specifies the dump file path, and the-Quiet parameter cancels the extra prompt. You can use notepad.exeas an experiment for the mouse to check whether dump is generated when notepad.exe is closed.
According to the above settings, after the problem occurs again, the c: \ dumps directory generates two dump files. The file names are:
PID-0 _ spawned0 _ 1st_chance_process_shut_down _ full_178c_datetime_0928.dmp PID-0 _ spawned0 _ 2nd_chance_cpluspluseh _ full_178C_2006-06-21_DateTime_0928.dmp
|
Note that the second name indicates that the C ++ exception of 2nd chance occurs! After opening the dump, we found the corresponding call stack and found that the customer forgot to catch the potential C ++ exception. After modifying the code and adding the corresponding catch, the problem is solved.
The problem is solved, but why can't Dr. Watson catch dump?
Of course, the question does not end with the solution. Since it is a crash caused by unhandled exception, why can't dr. Watson catch it? First, create two different programs to test dr. Watson's behavior:
Int _ tmain (INT argc, _ tchar * argv []) { Throw 1; Return 0; } Int _ tmain (INT argc, _ tchar * argv []) { Int * p = 0; * P = 0; Return 0; }
|
Indeed, for the first program, dr. Watson did not save the dump file. For the second one, dr. Watson works normally. It seems to be related to the exception type.
Recall carefully. When auto in AeDebug is set to 0, the system will pop up the previously mentioned red box. For the above two programs, the content of the box is different.
Here, the displayed dialog box is (the information saved with Ctrl + C when the dialog box appears ):
--------------------------- Microsoft Visual C ++ debug Library --------------------------- Debug error! Program: D: \ xiongli \ today \ exceptioninject \ debug \ exceptioninject.exe This application has requested the runtime to terminate it in an unusual way. Please contact the application's Support Team for more information. (Press retry to debug the Application) --------------------------- Abort retry ignore --------------------------- --------------------------- Exceptioninject.exe-application error --------------------------- The instruction at "0x00411908" referenced memory at "0x00000000 ". The memory cocould not be "written ". Click on OK to terminate the program Click on Cancel to debug the program --------------------------- OK cancel ---------------------------
|
The two are completely different! If you do more tests, you will find that the details of the dialog box are also related to the compilation mode release/debug.
The program can use the setunhandledexceptionfilter function to modify the default processing function of the unhanded exception. Here, when the C ++ runtime initializes CRT (C Runtime), it passes in the CRT processing function (msvcrt! Cxxunhandledexceptionfilter ). If an unhandled exception occurs, this function determines the number of the exception. If it is a C ++ exception, the first dialog box is displayed. Otherwise, it is handed over to the default processing function (Kernel32! Unhandledexceptionfilter. In the first case, the call stack is as follows:
USER32! Messageboxa Msvcr80d! _ Crtmessageboxa Msvcr80d! _ Crtmessage0000wa Msvcr80d! _ Vcrtdbgreporta Msvcr80d! _ Crtdbgreportv Msvcr80d! _ Crtdbgreport Msvcr80d! _ Nmsg_write Msvcr80d! Abort Msvcr80d! Terminate Msvcr80d! _ Cxxunhandledexceptionfilter Kernel32! Unhandledexceptionfilter Msvcr80d! _ Xcptfilter
|
In the second case, the CRT is handed over to the system for processing. Callstack is as follows:
Ntdll! Kifastsystemcallret Ntdll! Zwraiseharderror + 0xc Kernel32! Unhandledexceptionfilter + 0x4b4 Release_crash! _ Xcptfilter + 0x2e Release_crash! Maincrtstartup + 0x1aa Release_crash! _ Effect_handler3 + 0x61 Ntdll! Executehandler2 + 0x26 Ntdll! Executehandler + 0x24 Ntdll! Kiuserexceptiondispatcher + 0xe Release_crash! Main + 0x28 Release_crash! Maincrtstartup + 0x170 Kernel32! Baseprocessstart + 0x23
|
For more information, see:
setunhandledexceptionfilter http://msdn.microsoft.com/library/default.asp? url =/library/en-US/debug/base/setunhandledexceptionfilter. asp unhandledexceptionfilter http://msdn.microsoft.com/library/default.asp? url =/library/en-US/debug/base/unhandledexceptionfilter. asp |
Can the Information observed above explain dr. Watson's behavior? It seems to be related. To further confirm this problem, we can use windbg to replace dr. Watson and check whether dump can be obtained. If you only need to change the debugger to obtain dump, the problem is related to the debugger and has nothing to do with the exceptions thrown by the program. The specific method is:
1. Run drwtsn32.exe-I to register dr. Watson.
2. Open the AeDebug registry and find the debugger item, which should be drwtsn32-P % LD-E % LD-G.
3. Modify the debugger to c: \ debuggers \ windbg.exe-P % LD-E % LD-c ". Dump/MFH c: \ myfile. dmp; q ".
When unhanded exceptionoccurs, the system starts windbg.exe and loads it to the target process as a debugger. However, windbg.exe does not automatically obtain dump. Therefore, you must use the-C parameter to specify the initial command. Commands can be separated. Here, the. Dump/MFH c: \ myfile. dmp command is used to generate the dump file. The following qcommand causes windbg.exe to exit automatically after the dump is generated. With this method, for unhandled C ++ exception, windbg.exe can obtain the dump file. So I think the dr. Watson tool is defective in getting dump. The findings of the study are as follows:
Http://eparg.spaces.msn.com/blog/cns! 59bfc22c0e7e1a76! 1213. Entry