因为有多种异常,系统首先判断异常是否应发送给目标程序,如果应该发送,并且目标程序正处于被调试状态,则系统挂起程序,填写如下结构:
typedef _EXCEPTION_DEBUG_INFO
{
EXCEPTION_RECORD ExceptionRecord;
DWORD dwFirstchance;
}EXCEPTION_DEBUG_INFO;
将程序dwFirstchance设置为1,并向调试器发送EXCEPTION_DEBUG_EVENT消息。剩下的事情就由调试器全权负责了,调试器可能处理这个异常,也可能无法处理。
2. 如果调试器未能处理异常或程序根本没有被调试,系统就会查找是否存在与线程相关的异常处理过程,如果目标程序中存在与线程相关的异常处理过程,系统就调用程序的线程相关的SHE异常处理例程,交由其处理。
3. 与线程相关的异常处理过程可以有一个或多个,每个可以选择处理或者不处理异常,如果它不处理并且存在多个线程相关的异常处理过程,可交由链起来的其他异常处理过程进行处理,以此类推。
4. 如果程序线程的异常处理均选择不处理异常,如果程序出于被调试状态,操作系统仍会再次挂起程序通知调试器,这次EXCEPTION_DEBUG_INFO结构的dwFirstchance设置为0.
5. 如果程序未处于被调试状态或者调试器仍然未能够处理,并且程序调用了API函数SetUnhandledExceptionFilter设置了与进程相关的异常处理过程的话,系统转向对它的调用。
6. 如果程序没有设置进程相关的异常处理过程或者进程相关的异常处理过程也未能处理这个异常,系统会调用默认的系统异常处理程序,通常显示一个对话框,可以选择确定或者最后将其附加到调试器上的取消按钮。如果没有调试器能被附加于其上或调试器还是处理不了异常,系统就调用ExitProcess终结程序。
7. 不过终结之前,系统再次调用发生异常的线程中所有的异常处理过程,这是线程异常处理过程获得的最后清理未释放资源的机会,其后程序就终结了。
typedef _EXCEPTION_DEBUG_INFO
{
EXCEPTION_RECORD ExceptionRecord;
DWORD dwFirstchance;
}EXCEPTION_DEBUG_INFO;
将程序dwFirstchance设置为1,并向调试器发送EXCEPTION_DEBUG_EVENT消息。剩下的事情就由调试器全权负责了,调试器可能处理这个异常,也可能无法处理。
2. 如果调试器未能处理异常或程序根本没有被调试,系统就会查找是否存在与线程相关的异常处理过程,如果目标程序中存在与线程相关的异常处理过程,系统就调用程序的线程相关的SHE异常处理例程,交由其处理。
3. 与线程相关的异常处理过程可以有一个或多个,每个可以选择处理或者不处理异常,如果它不处理并且存在多个线程相关的异常处理过程,可交由链起来的其他异常处理过程进行处理,以此类推。
4. 如果程序线程的异常处理均选择不处理异常,如果程序出于被调试状态,操作系统仍会再次挂起程序通知调试器,这次EXCEPTION_DEBUG_INFO结构的dwFirstchance设置为0.
5. 如果程序未处于被调试状态或者调试器仍然未能够处理,并且程序调用了API函数SetUnhandledExceptionFilter设置了与进程相关的异常处理过程的话,系统转向对它的调用。
6. 如果程序没有设置进程相关的异常处理过程或者进程相关的异常处理过程也未能处理这个异常,系统会调用默认的系统异常处理程序,通常显示一个对话框,可以选择确定或者最后将其附加到调试器上的取消按钮。如果没有调试器能被附加于其上或调试器还是处理不了异常,系统就调用ExitProcess终结程序。
7. 不过终结之前,系统再次调用发生异常的线程中所有的异常处理过程,这是线程异常处理过程获得的最后清理未释放资源的机会,其后程序就终结了。