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

-未处理异常
异常过滤返回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。

-异常与调试器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值