-未处理异常
异常过滤返回EXCEPTION_CONTINUE_SEARCH,向上搜索,但无法搜索到处理部分,产生未处理异常。

// 负责处理未处理异常
// 进程初始化时,设置处理未处理异常过滤函数
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

线程相关:

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解释
1.允许对资源进行写入操作并继续执行
如线程写操作引起非法访问异常,UnhandledExceptionFilter会查看这个线程是否正在修改.exe或DLL模块的资源。
如是,UnhandledExceptionFilter调用VirtualProtect将资源页的保护属性设为PAGE_READWRITE,
并返回EXCEPTION_CONTINUE_EXECUTION,以允许失败的指令再执行。
2.将未处理异常报告给调试器
如当前程序在调试器控制下,它返回EXCEPTION_CONTINUE_SEARCH。
此时,通知当前进程的调试器。代码里可用IsDebuggerPresent来检测当前进程是否在调试器控制下。
3.通知我们设置全局异常过滤函数
调用设定的全局异常过滤程序。
如异常过滤函数返回值为:
EXCEPTION_EXECUTE_HANDLER或EXCEPTION_CONTINUE_EXECUTION,直接返回值给系统。
如返回EXCEPTION_CONTINUE_SEARCH,将未处理异常报告给调试器。

__CxxUnhandledExceptionFilter在调用UnhandledExceptionFilter前,会调用SetUnhandledExceptionFilter(NULL)

程序用C/C++运行库时,运行库会用try/except结构保护线程入口点函数,对应的异常过滤程序会调用C/C++运行库的_XcpFilter函数。
_XcpFilter在内部调用UnhandledExceptionFilter

-UnhandledExceptionFilter与WER的交互

默认处理下,未处理异常,会使windows弹出对话框,让用户选择,调试或终止进程。
HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting子项下的DontShowUI值为1时,就不会有任何对话框弹出,报告会在后台生成并发送给Microsoft服务器。
可改变DefaultConsent来决定错误发生时,是否给Microsoft服务器发报告。

调试程序时,一般不用等待报告生成和发送。
运行自动测试案列,一般也不希望WER对话框来破坏或终止自动测试。
将注册表Reporting子项的ForceQueue设为1,WER将在后台生成错误报告 。自动测试完,可用WER控制台,列出发生的问题并得到详细信息。

内核态线程抛出未处理异常,系统让相关设备驱动调用CrashDmp.sys在页文件中建立Crash Dump,再停止所有操作。
重启后,系统让WerFault运行,产生错误报告,并发送给Microsoft服务器。

-即时调试

-向量化异常和继续处理程序
程序可注册一个函数。
当异常发生或一个未处理异常脱离标准SEH控制时,这函数会被调用。

PVOID AddVectoredExceptionHandler(
// 0 传递的函数添加到列表尾端
// 非0 传递的函数添加到列表头部
ULONG bFirstInTheList,
// 指向向量化异常处理程序的指针
PVECTORED_EXCEPTION_HANDLER pfnHandler
);LONG WINAPI ExceptionHandler(
struct _EXCEPTION_POINTERS* pExceptionInfo
);// pHandler为之前Add...返回值
ULONG RemoveVectoredExceptionHandler(PVOID pHandler);PVOID AddVectoredContinueHandler(
// 0 传递的函数添加到继续处理函数列表尾端
// 非0 传递的函数添加到继续处理函数列表头部
ULONG bFirstInTheList,
PVECTORED_EXCEPTION_HANDLER pfnHandler
);ULONG RemoveVectoredContinueHandler(
PVOID pHandler
);

异常发生时,在执行SEH过滤程序前,将按列表顺序逐个调用这些函数。
一旦某个函数返回,EXCEPTION_CONTINUE_EXECUTION异常处理便结束,从发生异常处再次执行。
如返回EXCEPTION_CONTINUE_SEARCH,则执行列表下个函数。列表所有函数执行完,最后一个仍返回EXCEPTION_CONTINUE_SEARCH,则执行SEH过滤程序。

在SetUnhandledExceptionFilter安装的全局异常处理程序返回EXCEPTION_CONTINUE_SEARCH后,
按列表顺序逐个调用继续处理函数列表中函数。如返回EXCEPTION_CONTINUE_SEARCH,则执行列表下个函数。列表所有函数执行完,最后一个仍返回EXCEPTION_CONTINUE_SEARCH,则。。。

-C++异常与结构化异常比较
SEH是操作系统支持的功能。
C++异常处理是C++语言支持的。

如果开发C++应用,应使用C++异常,而非结构化异常。

Microsoft的Visual C++编译器使用操作系统的结构化异常机制来实现C++异常处理机制.
在创建C++的try块时,编译器生成一个SEH的__try块。
C++的catch语句对应SEH的异常过滤程序。
catch块中代码对应__except块中代码。
编译器会为C++的throw语句生成对windows RaiseException函数的调用。

void ChunkyFunky()
{
try
{
...
throw 5;
}
catch(int x)
{
...
}
...
}void ChunkyFunky()
{
__try
{
...
RaiseException(
Code = 0xE06D7363,
Flag = EXCEPTION_NONCONTINUABLE,
Args = 5
);
}
__except(
(ArgType == Integer) ?
EXCEPTION_EXECUTE_HANDLER :
EXECEPTION_CONTINUE_SEARCH
)
{
...
}
}

C++异常在内部实际是通过结构化异常来实现的,这使得我们可在一个应用中同时使用两种机制。
但C++语言不支持可恢复异常处理。对代码中不需要可恢复异常处理部分,坚持用C++异常处理,对代码中需要可恢复异常处理部分,可编用SEH,让他返回EXCEPTION_CONTINUE_EXECUTION。

-异常与调试器

windows核心编程---未处理异常,向量化异常处理与C++异常相关推荐

  1. 《Windows核心编程》读书笔记二十五章 未处理异常,向量化异常处理与C++异常

    第二十五章  未处理异常,向量化异常处理与C++异常 本章内容 25.1 UnhandledExceptionFilter函数详解 25.2 即时调试 25.3 电子表格示例程序 25.4 向量化异常 ...

  2. 未处理异常和C++异常——Windows核心编程学习手札之二十五

    未处理异常和C++异常 --Windows核心编程学习手札之二十五 当一个异常过滤器返回EXCEPTION_CONTINUE_SEARCH标识符时是告诉系统继续上溯调用树,寻找另外的异常过滤器,但当每 ...

  3. 异常处理程序和软件异常——Windows核心编程学习手札之二十四

    异常处理程序和软件异常 --Windows核心编程学习手札之二十四 CPU负责捕捉无效内存访问和用0除一个数值这种错误,并相应引发一个异常作为对错误的反应,CPU引发的异常称为硬件异常(hardwar ...

  4. C++Windows核心编程读书笔记(转)

    http://www.makaidong.com/(马开东博客) 这篇笔记是我在读<windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的 ...

  5. [C++]《Windows核心编程》读书笔记

    这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...

  6. [笔记]Windows核心编程《十六》线程栈

    系列文章目录 [笔记]Windows核心编程<一>错误处理.字符编码 [笔记]Windows核心编程<二>内核对象 [笔记]Windows核心编程<三>进程 [笔记 ...

  7. [笔记]Windows核心编程《十三》windows内存体系结构

    系列文章目录 [笔记]Windows核心编程<一>错误处理.字符编码 [笔记]Windows核心编程<二>内核对象 [笔记]Windows核心编程<三>进程 [笔记 ...

  8. 结束处理程序——Windows核心编程学习手札之二十三

    结束处理程序 --Windows核心编程学习手札之二十三 使用SEH可以只关注程序要完成任务,而运行中发生的错误,系统将会发现并通知.Windows引入SHE是为了便于操作系统的开发,使用SHE所造成 ...

  9. 线程与内核对象的同步——Windows核心编程学习手札之九

    线程与内核对象的同步 --Windows核心编程学习手札之九 用户方式下的线程同步机制具有速度快的特点,但有其局限性,对于许多应用程序来说,并不合适.例如,互锁函数家族只能在单值上运行,根本无法使线程 ...

最新文章

  1. Uva - 12050 Palindrome Numbers【数论】
  2. oracle数据库风险链接,数据库的风险主要来源
  3. 利用卷积神经网络对脑电图解码及可视化
  4. 打印表单_超市生鲜常用表单,打印出来直接用!(可收藏)
  5. 【Hibernate步步为营】--关联映射之多对一
  6. NOIP模拟测试23「mine·water·gcd」
  7. V210 UART TX 流程
  8. [c#基础]使用抽象工厂实现三层
  9. spring boot配置ip_Spring Cloud 配置中心高可用搭建
  10. java 多线程初入2
  11. 习题1.29 (积分方法的优化---simpson规则)
  12. KVM/QEMU桥接网络设置[zz]
  13. RHCE课程-RH253Linux服务器架设笔记五-APACHE服务器配置(2)
  14. 拼多多|后端开发工程师|一面| 远程牛客面试 | 凉经 (2021/08/14)
  15. 中国移动5G智慧港口典型业务场景分析
  16. 迅雷手机版苹果版_免费下载迅雷 iOS 版
  17. 软件测试工程师简历项目经验怎么写?--1000个已成功入职的软件测试工程师简历范文模板(含真实简历)
  18. 域名怎样实现自动跳转
  19. 计算机网络教程网线制作,图吧小白教程 篇二十六:手把手教你自制网线(夹网线水晶头)...
  20. 基于Java毕业设计智创员工管理系统源码+系统+mysql+lw文档+部署软件

热门文章

  1. Beautifu Soup库入门
  2. Dark Wonder(暗黑奇侠)学习笔记
  3. js里双间隔问号表达式,类似于A?B?C:D:E的表达式
  4. curl批量调用linux,shell的简单批量curl接口脚本
  5. python画康乃馨_康乃馨寓意好,养在家里装饰性强,这样做还能有效延长花期
  6. 2023年端午节高速免费吗?假期待办事项用手机定时提醒
  7. php aes算法解密后中文乱码,教程方法;PHP aes (ecb)解密后乱码问题电脑技巧-琪琪词资源网...
  8. 骨传导耳机怎么选购?2022年骨传导耳机入手指南!
  9. 每个程序员应该了解的97件事情
  10. 靠“喂喂喂”来测试实时语音质量靠谱吗?