why drwtson32 fails to generate the dump for 2nd C++ exception!
原贴地址:
http://eparg.spaces.msn.com/blog/cns!59BFC22C0E7E1A76!1213.entry
原贴时间:
2006-06-21
原贴作者:
eparg
int _tmain(int argc, _TCHAR* argv[])
{
throw 1;
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
int *p=0;
*p=0;
return 0;
}
Use “drwtsn32.exe –i” to register Dr. Watson and execute above code. For unhandled C++ exception, Dr. Watson fails to generate the dump. For unhandled AV, the dump is created fine.
If we change the AeDebug\Debugger in registry to use windbg as the following, the dump is created fine even for unhandled C++ exception.
C:\debuggers\windbg.exe -p %ld -e %ld -c ".dump /mfh C:\myfile.dmp ;q"
Why the drwtson32 ignores the dump for unhandled C++ exception?
With almost 6 hours research, got the answer, here are the steps:
My 1st step is to check if drwtson32 is launched. In AeDebug, I set Debugger as drwtson32 and set Auto to 0. I also add drwtson32.exe key in Image File Execution Options, and set the debugger to windbg.exe.
When the C++ EH occurs, windbg gets launched and attached to drwtson32. It means the unhandled C++ EH triggers drwtson32 successfully.
The next step is to check why drwtson32 fails to write the dump. Since I’ve no idea about the code logic of drwtson32, I switch to AV sample as research.
The AV triggers drwtson32 with windbg attached. I set bp on CreateFile API and it stops on the following call stack:
kernel32!CreateFileW
dbgeng!WriteDumpFile+0x2c]
dbgeng!DebugClient::WriteDumpFileInternal+0x6e
dbgeng!DebugClient::WriteDumpFile2+0x34
drwtsn32!CreateDumpFile+0xda
drwtsn32!DispatchDebugEventThread+0x1c7
kernel32!BaseThreadStart+0x34
Now I know the dump writing logic is in DispatchDebugEventThread function. I restart with AV Sample and go through the DispatchDebugEventThread to understand the logic. The function waits for debugging event, and handles it. For DEBUG_EVENT_EXCEPTION event, it queries for the ExceptionRecord. For the AV sample, when it gets the AV ExceptionRecord, it creates the dump.
With above understanding, I switch back to test The C++ EH sample. The DispatchDebugEventThread function is also invoked. However, drwtson32 does not get the C++ EH ExceptionRecord so there is no dump created.
Ok, our next question is, why there is no C++ EH ExceptionRecord passed in.
Just some days ago, I posted “How to debug UnhandleExceptionHandler”. The handler should be the last chain to do with the unhandled exception. So I decide to use my own handler as a test. When my handler returns 0, no matter AV or C++ EH, drwtson32 saves the dump correctly! When my handler returns 1, the debugger in AeDebug is not triggered at all.
Above test shows that the problem is somehow related to the UnhandleExceptionHandler. Since CRT uses special handler to deal with C++ EH, I decide to trace the CRT handler.
Since windbg is convenient, I change the AeDebug to use windbg. When windbg is triggered, it shows the following two callstacks for the two samples:
0012f864 7c822114 ntdll!KiFastSystemCallRet
0012f868 77e99c32 ntdll!ZwWaitForMultipleObjects+0xc
0012fb30 78138c06 kernel32!UnhandledExceptionFilter+0x746
0012fb50 0040119e MSVCR80!_XcptFilter+0x6a
0012fb5c 7813dfc4 win32!__tmainCRTStartup+0x137
0012fb70 7813bc8d MSVCR80!_EH4_CallFilterFunc+0x12
0012fb98 00401644 MSVCR80!_except_handler4_common+0x8d
0012fbb4 7c82eeb2 win32!_except_handler4+0x1f
0012fbd8 7c82ee84 ntdll!ExecuteHandler2+0x26
0012fc80 7c82ecc6 ntdll!ExecuteHandler+0x24
0012fc80 00401002 ntdll!KiUserExceptionDispatcher+0xe
0012ff7c 00401176 win32!main+0x2
0012ffc0 77e523cd win32!__tmainCRTStartup+0x10f
0012fff0 00000000 kernel32!BaseProcessStart+0x23
0012f210 7c822114 ntdll!KiFastSystemCallRet
0012f214 77e99c32 ntdll!ZwWaitForMultipleObjects+0xc
0012f4dc 7813adda kernel32!UnhandledExceptionFilter+0x746
0012f814 781346b6 MSVCR80!abort+0xeb
0012f844 7815e4ae MSVCR80!terminate+0x4d
0012f84c 77e995f7 MSVCR80!__CxxUnhandledExceptionFilter+0x39
0012faa4 78138c06 kernel32!UnhandledExceptionFilter+0xac
0012fac4 004011f9 MSVCR80!_XcptFilter+0x6a
0012fad0 7813dfc4 win32!__tmainCRTStartup+0x137
0012fae4 7813bc8d MSVCR80!_EH4_CallFilterFunc+0x12
0012fb0c 00401754 MSVCR80!_except_handler4_common+0x8d
0012fb28 7c82eeb2 win32!_except_handler4+0x1f
0012fb4c 7c82ee84 ntdll!ExecuteHandler2+0x26
0012fbf4 7c82eda4 ntdll!ExecuteHandler+0x24
0012fed4 77e55dea ntdll!RtlRaiseException+0x3d
0012ff34 78158dc3 kernel32!RaiseException+0x53
0012ff6c 00401018 MSVCR80!_CxxThrowException+0x46
0012ff7c 004011d1 win32!main+0x18
0012ffc0 77e523cd win32!__tmainCRTStartup+0x10f
0012fff0 00000000 kernel32!BaseProcessStart+0x23
The difference is the kernel32!UnhandledExceptionFilter reenters for C++ EH. The 2nd call of kernel32!UnhandledExceptionFilter is invoked by MSVCR80!abort.
MSVCR80!abort builds Exception record on stack and set ExceptionRecord.ExceptionCode to STATUS_FATAL_APP_EXIT. After that it clears the CRT CxxUnhandledExceptionFilte and calls kernel32!UnhandledExceptionFilter with the new created exception record. It seems the new built ExceptionRecord hides the original C++ EH, and prevents the C++ EH to pass to drwtson32.
With above information, I tried VC6 and VS2003 with the same samples. The drwtson32 is even not triggered with the C++ EH sample. By understanding the logic of the CxxUnhandledExceptionFilter and abort function, the earlier version before VC8 terminates the process in CRT handler directly so there is no reentry of kernel32!UnhandledExceptionFilter to trigger the debugger set in AeDebug.
As a summary, drwtson32 is not a reliable tool to obtain the dump file. We can try the following alternative:
1. Use IIS DebugDiag
2. In AeDebug, change debugger setting to the following to use windbg instead:
C:\debuggers\windbg -p %ld -e %ld -c ".dump /mfh C:\myfile.dmp ;q"
3. In Image File Execution Options setting, create a key with the target exe name. Change the debugger to the following:
C:\Debuggers\autodump.bat
Use the following as the bat file:
cscript.exe C:\Debuggers\adplus.vbs -crash -o C:\dumps -quiet -sc %1
分享到:
相关推荐
The main reason for making a virtual function inline is to place its definition in the class, either for convenience or to document its behavior, e.g., for accessors and mutators. The -inl.h Files...
- display library 'x' now uses the desktop size for the maximum guest resolution - ROM BIOS - Support for up to 2M ROM BIOS images - I/O Devices - 3 new 'pseudo device' plugins created by plugin ...
We convince ourselves that talent combined with a strong work ethic is the key to getting ahead, but also realize that combination often fails to yield results, without any deeper understanding as to ...
Concurrent Manager Fails to Start With Error Could not initialize the Service Manager FNDSM_{HOSTNAME}_{SID}(Doc ID 735148.1)
KEPServerEX fails while attempting to install the Visual C++ Redistributable Packages for Visual Studio 2013 (2013 CRT) and posts the following message: “CreateProcess failed (266). Please rerun ...
This patch addresses a number of issues in RAD Studio 10.4, pertaining to Delphi Compiler, the RAD Studio IDE in general and the new LSP-based Code Insight in particular, plus C++ Builder Android ...
Both MFC42LOC.DLL and CMCTLENU.DLL are language specific ... For this reason, there does not need to be an ENU version of the resource DLL, and therefore it fails to find one at runtime. This is normal.
create.sql This account will be the repository for all of the Oracle objects used by the utility and will be responsible for retrieving information from the file system for presentation to the ...
The software contains all files of the installation package except for the "Dump" folder contents. This LICENSE AGREEMENT ("LICENSE") defines what the USER may do with the SOFTWARE, and contains ...
This package provides a set of functions to control the VariSpec filter, which may be called from C or C++ programs. It incorporates all aspects of the filter communication, including low-level serial...
Seeing a program working for the first time as it reaches out on the web and starts gathering data never fails to provide a certain rush, feeling like you’ve circumvented the “normal way” of ...
The diagram included at the top represents the address partitioning for the 32-bit version of Windows 2000. Typically, the process address space is evenly divided into two 2-GB regions. Each process...
Oracle Database on Linux Fails to Start - ORA-27154 ORA-27300 ORA-27301 ORA-27302: failure occurred at: sskgpbitsper (Doc ID 2789636.1)
LSIP200232870 (DFCT) Add a Gen2 to Gen3 toggle function and a check for the PCI speed to MegaSCU/CLI [ PR : LSIP200231423 ] LSIP200232927 (DFCT) Port PR 198414 to MR5.4 (Headless Boot) ...
If every object in a collection of objects fails to have a certain property, then the probability that a random object chosen from the collection has that property is zero. Turning this around, if the...
When off it scans for the 'FILE' as encrypted text to find the start of a script Default:OFF 'Start Offset to Script Data' Here you can manually specify the offset were the script starts. ...
3. The Licensor reserves the right to block accounts/license codes that have not been paid for by the user in due time or that stood out through a very high number of updates until settlement of the ...
the latch should not be returned to the queue as an exception will be thrown. Thanks to Bushov Alexander. For complete information on commons-pool, including instructions on how to submit bug ...