环境是各种Win平台(XP及更高版本)上的VC ++ 9
我正在编写一个未处理的异常处理程序。我的内核时代有一个模糊的回忆,抓到一个EXCEPTION_GUARD_PAGE是不好的,因为这是为了告诉操作系统放大堆栈而生成的。
我的问题有两个:
在用户空间中是否会发生此类异常?
如果是这样,抓住它是否安全?
我对用它做任何事都不是特别感兴趣。我只是想知道我是否需要将特殊代码放入而不是捕获它(因为我现在正在捕捉所有内容)。
__更新:__
我已经回忆起我的来源,这是Raymond Chen的博客(http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx)
我最初担心的是,当捕获所有异常时,如果我捕获EXCEPTION_GUARD_PAGE,我可能会阻止操作系统看到异常并扩大堆栈。
进一步思考,我怀疑EXCEPTION_GUARD_PAGE可能在生成它的读/写操作期间在内核中处理,因此永远不会到达我的用户空间代码。
我想我正在找人确认(或反驳)那个。
__第二次更新:__
我还没有选择答案,因为没有人真正回答过这个问题。我会保持开放,希望有人可能会提供我所寻求的信息。
__第三次更新__
仍然生活在(微弱的)希望中。
__第四次更新__
好吧,我从来没有得到过有用的答案。当我问这个问题时,我已经完成了我写的模块。我认为问题是,出于实际目的,已经死了。我可能不会再次更新。
答案 0 :(得分:3)
使用VirtualProtectEx()设置页面以生成STATUS_GUARD_PAGE_VIOLATION,并且PAGE_GUARD标志为documented procedure。只能为页面生成一次异常,因此在处理异常时不会有任何危险。
我没有为异常做任何特别的事情,但这并不能证明太多,获得此异常将非常罕见。在我们的任何崩溃报告中都没见过一次。
该功能实际上是用于生成堆栈溢出异常。你确实需要特别处理,因为剩下这么少的堆栈。我认为这就是你在问题中提到警告的地方。但是它永远不会生成页面保护异常,它在内核级别处理,然后转换为堆栈溢出。
答案 1 :(得分:1)
根据我对virtualquery的观察,它类似于内核模式的情况。如果访问的保护页堆栈不属于访问线程,则调试器可以捕获异常。无论如何,你应该已经有了答案。
答案 2 :(得分:0)
根据MSDN:
线程访问已分配的内存 使用PAGE_GUARD修饰符。
除非你有一个错误,否则听起来应该永远不会发生;所以我会相应地处理它。
修改强>
操作系统异常处理程序在您之前注册,因此自行处理并不意味着操作系统无法首先查看它。