Windows系统蓝屏时,蓝屏代码0x000000d1

?技术资讯作者:阿强 ?2019-10-30 22:09

就像Linux系统报panic一样,Windows系统只有内核态的代码执行异常才会导致系统蓝屏。其实Windows系统是可以选择忽略错误,但Windows认为原本发生在RAM的错误,如果不终止,很有可能导致更多的错误,且可能影响到Disk存储,造成数据损坏,因此Windows选择了蓝屏显示错误并终止系统。

Windows系统蓝屏时系统都在后台做了什么?

蓝屏(Window 7系统)

当异常发生在内核态时,系统将捕捉这个异常(由处理器自动跳转至已注册的异常处理函数中),并自动调用KeBugCheckEx函数。调用该函数时,传递了1个stop code(数字)和四个参数(与stop code相关)。我们平常在蓝屏时,在底部看到一行类似的字符串

```

*** STOP:0x000000D1(0xA35DB800,0x0000001C,0x00000000,0x9879C3DD)

```

其实第1个就是stop code,后面是KeBugCheckEx收到的四个参数,第4个参数往往是发生异常的代码地址。在蓝屏顶部还有一个stop code对应文本格式说明,例如“DRIVER_IRQL_NOT_LESS_OR_EQUAL”。

Windows系统蓝屏时系统都在后台做了什么?

蓝屏(Window 10系统)

接下来,我们来看Windows调用KeBugCheckEx时,该函数都做了什么。

当KeBugCheckEx函数被调用时,该函数将停止所有处理器的中断,然后切换显示为低分辨率的VGA模式,接着绘制蓝色的背景,并显示stop code和说明信息。最后,它将调用两个回调集合:

1. 设备驱动通过KeRegisterBugCheckCallback函数注册的回调函数,以便设备驱动能够有机会停止设备

2. 设备驱动通过KeRegisterBugCheckReasonCallback函数注册的回调函数,以便设备驱动能够将崩溃时的关键信息写到磁盘,形成系统异常dump文件,以便后续的问题分析。这有点类似Android的ANR trace生成机制。

如果知道了系统在蓝屏时都执行的操作,后续如果我们需要在蓝屏时做一些特殊的操作,就只需要写个驱动并注册一个回调函数。比如,有些服务器虚拟化厂商在虚拟机蓝屏时,能够自动截屏,并自动重启系统,估计就是通过这个功能实现。