First chance exception 与 Second chance exception

2010年08月05日 星期四 下午 11:25

参考:
1.
http://blog.sina.com.cn/s/blog_540880190100fuaz.html
2. http://blog.csdn.net/qsycn/archive/2010/01/27/5260389.aspx.
3.
http://www.cnblogs.com/awpatp/archive/2010/06/15/1758763.html

我的理解:
1. 当异常发生后,系统会首先检查是否有调试器加载,如果有则调试器会收到异常消息,并决定是否中断程序的执行。这叫First chance exception。如果没有调试器加载,则转2,如果调试器决定忽略First chance exception,同样转2,如果调试器不忽略,则程序被中断,这意味着如果程序中即使有异常处理代码(catch块)它们也不会被执行。所以调试器通常忽略First chance exception,而让用户的异常处理代码(catch块)去处理。

2. 如果没有调试器加载或者调试器忽略了First chance exception,控制流程转向用户的异常处理代码(catch块)。如果没有发现相应的catch块,系统使用自带的异常处理块处理这个异常(转3),如果发现相应的catch块,则执行之,异常处理结束。

3. 系统自带的异常处理程序检查是否有调试器加载,如果有,则中断程序并将控制权交给调试器。这时的异常叫做Second chance exception。此时调试器就完全控制了程序,程序实际上已经挂掉了。如果没有调试器加载,转4.

4. 异常发生了,但用户没有相应的异常处理代码,也有没有调试器加载,这时候就会弹出程序崩溃(Crash)提示。Windows启动注册在注册表里面的默认调试器,一般情况下,Windows的默认调试器是Dr Watson,这个调试器的工作就是弹出著名的“调试还是终止,这个问题”对话框(或者是“是否将错误报告发送给微软?”对话框)。.

比如VS在调试模式下运行程序,输出窗口信息为:


First-chance exception at 0x004117fe in ***: 0xC0000005: Access violation writing location 0x00000000.
Unhandled exception at 0x004117fe in ***: 0xC0000005: Access violation writing location 0x00000000.

其中0xC0000005是访问违例的异常标识符,0x004117fe是异常产生时的程序地址,0x00000000是Access violation的地址。这说明VS收到了First chance exception但将其忽略了,但程序中没有相应的catch块,导致第二行消息出现,Unhandled exception ,即Second chance exception,VS弹出一个对话框提示说Unhandled exception...,并有Break, Continue, Ignore(灰色)可供选择)。如果有相应的catch块,则不会输出第二行信息,也不会有对话框弹出。

First chance exception 与 Second chance exception_第1张图片

以上是在VS调试模式下运行的,如果直接运行,则弹出对话框,提示说:
*** has encountered a problem and needs to close. We are sorry for the inconvenience.
If you were in the middle of something, the information you were working on might be lost.
For more information about this error, click here.
Debug   Close

First chance exception 与 Second chance exception_第2张图片

这对应上面的4。运行Spy++发现上面对话框是C:/WINDOWS/system32/dwwin.exe弹出来的,而不是testCPP。dwwin.exe的描述是Microsoft Application Error Reporting

在Windbg里可以设置是否忽略First chance exception

另:
可以利用SetUnhandledExceptionFilterMiniDumpWriteDump,以便在程序崩溃(即产生未处理的异常)时记录dump文件便于后来分析,这两个函数都很简单,就不介绍了。

 

你可能感兴趣的:(windows,exception,Microsoft,application,Access,Crash)