驱动中为啥少有异常处理的代码?

45 篇文章 7 订阅
35 篇文章 5 订阅

    今天整理ppt,突然想到一个现象:在WRK以及winddk sample源码中很少见到异常处理相关的影子(指windows结构化异常处理SEH:__try/__exception,而不是C++标准提供的try/catch,kernel不支持C++异常)。按说,内核本身具有完整的异常处理机制,驱动作为内核的一部分,如果使用了异常处理块,必然受到异常处理机制的保护。

    我首先想到的是在DISPATCH_LEVEL上发生了缺页异常,由于换页线程不被调度,因此该异常始终无法解决。在这样的情景下,异常处理的确没有任何意义。但是排除这种情况我实在想不出不使用异常处理的理由。查了一下MSDN "Handling Exceptions",他的解释是:

1.读写来自用户空间的内存时,需要在try/except块中调用ProbeForWrite/ProbeForRead来检查这部分内存是否可用。形如:

try {
    ...
    ProbeForWrite(Buffer, BufferSize, BufferAlignment);

    /* Note that any access (not just the probe, which must come first,
     * by the way) to Buffer must also be within a try-except.
     */
    ...
} except (EXCEPTION_EXECUTE_HANDLER) {
    /* Error handling code */
    ...
}

这部分内容我并没有觉得陌生,在Wrk源码中不乏有像NtReadFile/NtWriteFile这样从用户态进入到内核态的stub函数,在其入口处会调用ProbeForxxx函数来检查参数的可用性。

2.驱动中可以调用ExRaiseAccessViolation等函数抛出异常,驱动需要及时处理这些异常。我想,应该没人会冒着蓝屏的风险做这样的操作吧,所以这个可以忽略。

3.部分Mm*系列的DDI,因为访问了用户空间内存需要由try/exception保护。这部分DDI在其Remark部分标注有类似"Calls to MmProbeAndLockPages must be enclosed in a try/except block. If the pages do not support the specified operation, the routine raises the STATUS_ACCESS_VIOLATION or other exceptions."的字样。换句话说,这类DDI是已知的雷区,进入前得有出意外的准备。

观察上面3点,至少可以确定OS对驱动提供了有限的异常处理能力。但是,还是没有让我释疑。倒在另一篇MSDN "Exception Handling When Accessing User-Mode Memory"中找到一句话:

"Note Aside from accessing and copying the user-mode value into a local variable, 
the driver should not perform any other operations inside the __try block.
 Other operations can cause their own exceptions to occur.
 The operating system handles these exceptions differently."

意为:除了读写用户空间内存时需要使用try/except块意外,其他操作不宜加入自己的异常处理代码,由于与OS的异常处理行为不同,可能会引发其他异常(这可能是指"双误异常")。说实话,这个解释,还是有点牵强,最后,在这个页面上找到勉强让我信服的解释:

"Exceptions processing takes a lot of space in stack 
and this can cause its overflow as stack size in kernel mode is very small (about 12 Kb). 
That's why one should work with exceptions very carefully."


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值