why drwtson32 fails to generate the dump for 2nd C++ exception!

原创 2007年09月19日 21:30:00

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

设置C++崩溃时生成Dump文件

设置C++崩溃时生成dump文件Dump 文件是进程的内存镜像 , 可以把程序的执行状态通过调试器保存到dump文件中 ; Dump 文件是用来给驱动程序编写人员调试驱动程序用的 , 这种文件必须用专...
  • tojohnonly
  • tojohnonly
  • 2017年06月02日 15:48
  • 1168

adrci 问题打包

[oracle@db01 ~]$ adrci ADRCI: Release 11.2.0.4.0 - Production on Mon Feb 29 10:16:09 2016 Copyrigh...
  • EVISWANG
  • EVISWANG
  • 2016年02月29日 10:28
  • 297

windows客户端开发--让你的客户端崩溃之前生成dump文件

debug时候我们可以很快速、精确的定位问题所在。但是对于release版本,我们往往无能为力。尤其面对一群难缠的客户,情况就会更加糟糕。而且对于release版本来说,crash的时候日志系统往往起...
  • wangshubo1989
  • wangshubo1989
  • 2016年04月08日 23:18
  • 13259

C++程序崩溃生成dump

程序在运行时,难免会有一些异常情况发生,特别是在条件不容许去挂调试器的时候,如何快速的定位错误的方法就显得很重要。 日志一直都是一种很重要的定位错误的方法,出得好的日志可以方便程序员快速的定位问题所...
  • whatday
  • whatday
  • 2015年04月03日 17:42
  • 10622

异常处理与MiniDump详解(4) MiniDump

转载自:http://blog.csdn.net/vagrxie/article/details/4398721
  • huanying_huanying
  • huanying_huanying
  • 2014年06月20日 23:47
  • 825

C++ 内存相关

常见的内存错误及其对策 发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。有时用户怒气冲冲地把你找来...
  • leexurui
  • leexurui
  • 2015年10月05日 22:31
  • 616

C++ 记录Windows程序崩溃时的dumpfile

【原理】       windows程序当遇到异常,没有try-catch或者try-catch也无法捕获到的异常时,程序就会自动退出,如果这时候没有dump文件的话,我们是没有得到任何程序退出的信...
  • aoshilang2249
  • aoshilang2249
  • 2015年06月19日 21:23
  • 2474

php+gd库的源码安装

PHP+GD安装   一、下载软件 gd-2.0.35.tar.gz          http://www.boutell.com/gd/ jpegsrc.v6b.tar.gz       ...
  • pang040328
  • pang040328
  • 2013年12月08日 21:26
  • 7630

初探MeidaPlayer底层实现(二)

接着上一篇文章继续研究MeidaPlayer 两个入手点: 1 private static native final void native_init(); 2 private native fi...
  • qq_23194021
  • qq_23194021
  • 2017年01月22日 21:54
  • 377

利用windbg分析dump文件

windbg是windows下一个分析调试的工具,功能非常强大。这里主要记录利用windbg来分析windows蓝屏时所产生的内存转储文件*.dmp。 1,下载: http://www.micro...
  • zhongguoren666
  • zhongguoren666
  • 2013年04月12日 14:54
  • 13620
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:why drwtson32 fails to generate the dump for 2nd C++ exception!
举报原因:
原因补充:

(最多只允许输入30个字)