错误检查 0xD1:DRIVER_IRQL_NOT_LESS_OR_EQUAL
DRIVER_IRQL_NOT_LESS_OR_EQUAL 错误检查的值为 0x000000D1。 这表示内核模式驱动程序在进程 IRQL 过高时试图访问可分页内存。
重要
这篇文章适合程序员阅读。 如果你是在使用计算机时收到蓝屏错误代码的客户,请参阅蓝屏错误疑难解答。
DRIVER_IRQL_NOT_LESS_OR_EQUAL 参数
参数 | 说明 |
---|---|
1 |
引用的内存。 |
2 |
引用时的 IRQL。 |
3 |
|
4 |
引用内存的地址。 在此地址上使用 ln(列出最近的符号)可以查看函数的名称。 |
原因
若要确定原因,需要 Windows 调试器、编程体验以及访问故障模块的源代码。
通常,发生此错误时,驱动程序尝试访问可分页(或完全无效)的地址,而中断请求级别 (IRQL) 太高。 这可能是由于:
在 DISPATCH_LEVEL 或更高级别执行时,取消引用错误指针(例如 NULL 或释放的指针)。
在 DISPATCH_LEVEL 或更高级别访问可分页数据。
在 DISPATCH_LEVEL 或更高级别执行可分页代码。
如果能够识别出导致错误的驱动程序,则会将其名称打印在蓝屏上,并存储在内存中的 (PUNICODESTRING) KiBugCheckDriver 位置。 可以使用一个调试器命令 dx(显示调试器对象模型表达式)来显示此内容:dx KiBugCheckDriver。
此错误检查通常是由使用了不正确内存地址的驱动程序引起的。
页面错误可能的原因包括以下事件:
该函数被标记为可分页,并且在提升的 IRQL(包括获取锁)下运行。
对另一个驱动程序中的函数进行了函数调用,该驱动程序已卸载。
函数是通过使用无效指针的函数指针调用的。
有关 Windows IRQL 的详细信息,请参阅由 Pavel Yosifovich、Mark E. Russinovich、David A. Solomon 和 Alex Ionescu 编写的 Windows 内部资料第 7 版第 1 部分。
解决方法
如果问题是由正在开发的驱动程序引起的,请确保在错误检查时正在执行的函数是:
- 未标记为可分页
- 不调用任何其他可以调出的内联函数。
!analyze 调试程序扩展显示有关错误检查的信息,有助于确定根本原因。 下面的示例是 !analyze 的输出。
DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: fffff808add27150, memory referenced
Arg2: 0000000000000002, IRQL
Arg3: 0000000000000000, value 0 = read operation, 1 = write operation
Arg4: fffff808adc386a6, address which referenced memory
如果能够识别出导致错误的驱动程序,则会将其名称打印在蓝屏上,并存储在内存中的 (PUNICODESTRING) KiBugCheckDriver 位置。 可以使用一个调试器命令 dx(显示调试器对象模型表达式)来显示此内容:dx KiBugCheckDriver
。
0: kd> dx KiBugCheckDriver
KiBugCheckDriver : 0xffffc6092de892c8 : "Wdf01000.sys" [Type: _UNICODE_STRING *]
如果转储文件中有陷阱帧,请使用 .trap 命令将上下文设置为提供的地址。
若要开始调试这种类型的错误检查,请使用 k、kb、kc、kd、kp、kP、kv(显示堆栈回溯)命令检查堆栈跟踪。
在调试器中,运行 !irql 命令用于在调试器中断之前显示目标计算机上处理器的 IRQL 信息。 例如:
0: kd> !irql
Debugger saved IRQL for processor 0x0 -- 2 (DISPATCH_LEVEL)
在这种类型的错误检查的大多数情况下,问题不在于 IRQL 级别,而在于正在访问的内存。
由于此错误检查通常是由使用了不正确内存地址的驱动程序引起的,因此请使用参数 1、3 和 4 进行进一步调查。
将 ln(列出最近符号)与参数 4 一起使用以查看调用的函数的名称。 还要检查 !analyze 输出,以确定错误代码是否已识别。
在参数 1 地址上使用 !pool 查看是否为分页池。 使用 !address 和高级 !pte 命令以了解有关此内存区域的更多信息。
使用显示内存命令检查参数 1 中命令中引用的内存。
使用 u、ub、uu (unassemble) 命令查看引用参数 4 中内存的地址中的代码。
使用 lm t n
命令列出内存中加载的模块。 使用 !memusage 并检查系统内存的一般状态。
驱动程序验证程序
驱动程序验证程序是一个实时运行的工具,用于检查驱动程序的行为。 例如,驱动程序验证程序检查内存资源(如内存池)的使用。 如果在执行驱动程序代码时标识错误,它会主动创建一个异常,以允许进一步检查该部分驱动程序代码。 驱动程序验证程序管理器内置于 Windows 中,可在所有 Windows 电脑上使用。
若要启动驱动程序验证程序管理器,请在命令提示符下键入 verifier。 你可以配置要验证的驱动程序。 验证驱动程序的代码在运行时会增加开销,因此请尝试验证尽可能少的驱动程序。 有关详细信息,请参阅驱动程序验证程序。
注解
如果你不具备使用 Windows 调试器来解决此问题的能力,则可以使用一些基本的故障排除技术。
在事件查看器中检查系统日志以获取其他错误消息,这可能有助于识别导致此错误检查的设备或驱动程序。
如果在错误检查消息中标识了驱动程序,请禁用该驱动程序,或与制造商联系以获取驱动程序更新。
确保安装的任何新硬件都与已安装的 Windows 版本兼容。 例如,可以在 Windows 10 规范中获取所需硬件的相关信息。
有关其他常规疑难解答信息,请参阅蓝屏数据。