24.1 SetUnhandledExceptionFilter未处理异常--《Windows核心编程》
对于未处理异常,例如异常过滤返回EXCEPTION_CONTINUE_SEARCH,向上搜索,但无法搜索到处理部分,产生未处理异常。Windows提供了 SetUnhandledExceptionFilter 函数,给我们处理异常的最后机会,否则 Windows 会正式认为这个异常没有得到处理。
默认情况下,如果没有设置 SetUnhandledExceptionFilter 函数,对于未处理异常,会调用操作系统的默认异常处理代码 UnhandledExceptionHandler。
通常应该在进程初始化阶段调用这个函数,一旦调用,进程中所有线程的未抛出异常都会导致 SetUnhandledExceptionFilter 参数所指定的的异常过滤函数的执行。
// 负责处理未处理异常
// 进程初始化时,设置处理未处理异常过滤函数
PTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(
PTOP_LEVEL_EXCEPTION_FILTER pTopLevelExceptionFilter
);
参数是一个异常过虑函数,原型必须与下面类似
// 返回值和结果
// EXCEPTION_EXECUTE_HANDLER 进程终止
// EXCEPTION_CONTINUE_EXECUTION 从抛出异常处再执行
// EXCEPTION_CONTINUE_SEARCH 不处理
LONG WINAPI TopLevelUnhandledExceptionFilter(
PEXCEPTION_POINTERS pExceptionInfo
);
C/C++运行函数安装的默认的全局异常过滤程序: __CxxUnhandledExceptionFilter,用 NULL 调用 SetUnhandledExceptionFilter 将全局未处理异常过滤程序设回 UnhandledExceptionFilter
#include <windows.h>
#include <stdio.h>
long __stdcall callback(_EXCEPTION_POINTERS* excp)
{
MessageBox(0, "Error", "error", MB_OK);
printf("Error address %x\n", excp->ExceptionRecord->ExceptionAddress);
printf("CPU register:\n");
printf("eax %x ebx %x ecx %x edx %x\n", excp->ContextRecord->Eax,
excp->ContextRecord->Ebx, excp->ContextRecord->Ecx,
excp->ContextRecord->Edx);
return EXCEPTION_EXECUTE_HANDLER; // 进程终止
}
int main(int argc, char* argv[])
{
PTOP_LEVEL_EXCEPTION_FILTER pException = SetUnhandledExceptionFilter(callback);
_asm int 3 // 只是为了让程序崩溃
return 0;
}
我们都知道,每个线程的执行都是从 NTDLL.dll 中的函数 BaseThreadStart 开始的:
VOID BaseThreadStart(
PTHREAD_START_ROUTINE pfnStartAddr,
PVOID pvParam
)
{
__try
{
ExitThread((pfnStartAddr)(pvParam));
}
__except (UnhandledExceptionFilter(GetExceptionInformation()))
{
ExitProcess(GetExceptionCode());
}
}
// 上述UnhandledExceptionFilter的返回值和结果
// EXCEPTION_EXECUTE_HANDLER 执行ExitProcess,进程退出
// EXCEPTION_CONTINUE_EXECUTION 从抛出异常处再次执行
// EXCEPTION_CONTINUE_SEARCH 未处理异常
// 上述UnhandledExceptionFilter的返回值和结果
// EXCEPTION_EXECUTE_HANDLER 执行ExitProcess,进程退出
// EXCEPTION_CONTINUE_EXECUTION 从抛出异常处再次执行
// EXCEPTION_CONTINUE_SEARCH 未处理异常
如果我们的线程抛出一个异常,并且所有安装的异常过滤程序都返回 EXCEPTION_CONTINUE_SEARCH,系统提供的一个特殊函数 UnhandledExceptionFilter 将会被调用。
本书讨论的是用户态的开发。对内核态线程抛出未处理异常,在蓝屏前,系统让相关设备驱动调用 CrashDmp.sys在页文件中建立 Crash Dump,再停止所有操作。重启后,会查看页文件是否包含了一个 Crash Dump,如果有表示数据得到了存储 ,系统让WerFault运行,产生错误报告,并发送给Microsoft服务器。
24.1 SetUnhandledExceptionFilter未处理异常--《Windows核心编程》的更多相关文章
- C++Windows核心编程读书笔记
转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...
- 【转】《windows核心编程》读书笔记
这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...
- windows核心编程 - 线程同步机制
线程同步机制 常用的线程同步机制有很多种,主要分为用户模式和内核对象两类:其中 用户模式包括:原子操作.关键代码段 内核对象包括:时间内核对象(Event).等待定时器内核对象(WaitableTim ...
- 【windows核心编程】 第八章 用户模式下的线程同步
Windows核心编程 第八章 用户模式下的线程同步 1. 线程之间通信发生在以下两种情况: ① 需要让多个线程同时访问一个共享资源,同时不能破坏资源的完整性 ② 一个线程需要通知其他线程 ...
- 【windows核心编程】 第六章 线程基础
Windows核心编程 第六章 线程基础 欢迎转载 转载请注明出处:http://www.cnblogs.com/cuish/p/3145214.html 1. 线程的组成 ① 一个是线程的内核 ...
- 《Windows核心编程》读书笔记 上
[C++]<Windows核心编程>读书笔记 这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对 ...
- 《windows核心编程系列》十六谈谈内存映射文件
内存映射文件允许开发人员预订一块地址空间并为该区域调拨物理存储器,与虚拟内存不同的是,内存映射文件的物理存储器来自磁盘中的文件,而非系统的页交换文件.将文件映射到内存中后,我们就可以在内存中操作他们了 ...
- windows核心编程---第八章 使用内核对象进行线程同步
使用内核对象进行线程同步. 前面我们介绍了用户模式下线程同步的几种方式.在用户模式下进行线程同步的最大好处就是速度非常快.因此当需要使用线程同步时用户模式下的线程同步是首选. 但是用户模式下的线程同步 ...
- windows核心编程-互斥器(Mutexes)
线程同步的方式主要有:临界区.互斥区.事件.信号量四种方式. 前边讲过了临界区线程同步-----windows核心编程-关键段(临界区)线程同步,这章我来介绍一下互斥器(Mutexes)在线程同步中的 ...
- 【Windows】windows核心编程整理(上)
小续 这是我11年看<windows核心编程>时所作的一些笔记,现整理出来共享给大家 windows核心编程整理(上) windows核心编程整理(下) 线程的基础知识 进程是不活泼的,进 ...
随机推荐
- treeselect 表单验证解决方法
https://www.cnblogs.com/wxqworld/p/11203603.html
- C#设计模式08——桥接模式的写法
什么是C#桥接模式?桥接模式是一种结构型设计模式,它可以将抽象部分与实现部分分离,使它们可以独立地变化.这种模式通过将实现细节从抽象类中分离出来,从而让它们可以根据需要独立变化. 为什么要使用C#桥接 ...
- 数字IC设计全流程介绍
数字IC设计全流程设计 掌握数字集成电路设计的流程 数字设计流程中每个阶段主要做哪些工作? 数字设计流程中每个阶段使用的主要EDA工具? 数字电路常用软件公司Mentor(questasim),Syn ...
- 【SHELL】[ ]、[[ ]]条件判断结构
输入参数包含 'arg-m' 时,会输出 Hit Arg-M 和 Hit Arg-N [[ ${EXEC_PARAMS[@]} =~ 'arg-m' ]] && echo " ...
- 【FreeRTOS】内核查找最高优先级就绪任务
查找最高优先级就绪任务 FreeRTOS\Source\tasks.c #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) /* If confi ...
- 【BUS】动画图解嵌入式常见的通讯协议:SPI、I²C、UART、红外 ......
SPI传输 SPI数据传输 SPI数据传输 SPI时序信号 I2C传输 2C总线寻址 UART传输 PC-UART-MCU RS-232电平转换 红外控制 红外通信 红外信号接收.放大.整形 红外控制 ...
- 【canvas】 绘制七巧板
效果图: 代码 : <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- linux环境C语言实现:h264与pcm封装成AVI格式
前言 拖了很久的AVI音视频封装实例,花了一天时间终于调完了,兼容性不是太好,但作为参考学习使用应该没有问题. RIFF和AVI以及WAV格式,可以参考前面的一些文章.这里详细介绍将一个H264视 ...
- [转帖][MySQL 8.2.0] 从参数变化解读 MySQL 8.2.0 发版说明
https://www.mryunwei.com/482476.html 日前,MySQL 8.2.0 创新版本已正式上线,并提供安装包下载,但 docker 镜像尚未更新. 在 MySQL 8.1. ...
- [转帖]TNS-12535 TNS-00505的处理方法
硬件说明: 操作系统版本:ORACLE LINUX 6.3 64位 数据库版本:11.2.0.3 64位 问题说明: 在检查数据库的alert日志的时候,发现大量的12170和TNS-12535 ...