zoukankan      html  css  js  c++  java
  • 异常处理流程

         

         对于CPU级的异常,CPU会通过IDT表寻找异常的处理函数,也就是KiTrapXX例程,会调用CommonDispatchException准备参数,然后调用内核分发函数KiDispatchException进行异常分发。

         下面的图是内核异常分发总管KiDispatchException处理的流程。

    内核态异常的分发过程:
      1.如果PreviousMode为KernelMode(0),那么对于第一轮处理机会,KiDispatchException会试图先通知内核调试器来处理该异常。
      2.内核变量KiDebugRoutine用来标识内核调试引擎交互的接口函数。当内核调试引擎启用时,KiDebugRoutine指向内核调试引擎KdpTrap,这个函数会进一步把异常信息封装为数据包发送给内核调试器,当调试内核调试引擎没有启用时,KiDebugRoutine指向KdpStub函数,简单处理后返回
      3.如果KiDebugRoutine返回TRUE,也就是内核引擎处理了异常,那么KiDispatchException便停止继续分发,准备返回。如果KiDebugRoutine返回FALSE,也就是没有处理该异常,那么KiDispatchException会调用RtlDispatchException函数,试图寻找已经注册的结构化异常处理器(SEH)。会遍历异常登记链表,依次执行每个异常处理器。如果某个处理器除了了,RtlDispatchException返回TRUE,否则返回FALSE
      4.RtlDispatchException返回FALSE,KiDispatchException会试图给内核调试器第二次机会,如果KiDebugRoutine仍然返回FALSE,那么KiDispatchException会认为这是无人处理的异常,会调用KeBugCheckEx

    用户态异常的分发过程:
      1.如果前一模式是用户模式,即PreviousMode参数等于UserMode(1),对于第一次处理机会,KiDispatchException会试图将异常分发给用户态的调试器,如果DebugPort不为空,将异常发送给调试子系统,调试子系统将异常发送给调试器,如果处理了异常分发结束。
      2.如果调试器没有处理该异常,KiDispatchException修改用户态栈,返回用户层之后执行KiUserExceptionDispatcher,此函数会调用RtlDispatchException来寻找异常处理器,首先遍历VEH,然后遍历SEH,。如果RtlDispatchException返回FALSE,并且当前进程在被调试,那么KiUserExceptionDispatcher会调用ZwRaiseException并将FirstChance设置为FALSE,进行第二轮分发。如果没有被调试,结束进程。
      3.ZwRaiseException会通过内核服务NtRaiseException把异常传递给KiDispatchException来进行分发。第二次,将异常传递给调试器,如果没有处理将异常分配给ExceptionPort异常端口监听者处理,如果返回FALSE,结束进程。

  • 相关阅读:
    PHP 计算页面执行时间
    PHP 实现多服务器共享 SESSION 数据
    你不了解PHP的10件事情
    智能的PHP缩图类
    php配置文件php.ini 中文版
    PclZip:强大的PHP压缩与解压缩zip类
    https 加载问题
    docker 安装sentry
    requests ssl 报错
    解决长时间计划任务rsync同步进程数过多
  • 原文地址:https://www.cnblogs.com/aliflycoris/p/5744539.html
Copyright © 2011-2022 走看看