如何使用驱动程序验证程序来解决 Windows 驱动程序问题

针对 Windows XP 的支持已终止

Microsoft 已于 2014 年 4 月 8 日终止了针对 Windows XP 的支持。该更改已影响到您的软件更新和安全选项。 了解这一措施对于您的含义以及如何继续保持受保护状态。

针对 Windows Server 2003 的支持已于 2015 年 7 月 14 日终止。

Microsoft 已于 2015 年 7 月 14 日终止了对于 Windows Server 2003 的支持。该更改已影响到您的软件更新和安全选项。 了解这一措施对于您的含义以及如何继续保持受保护状态。

重要说明:本文包含有关修改注册表的信息。修改注册表之前,一定要先进行备份,并且一定要知道在发生问题时如何还原注册表。有关如何备份、还原和编辑注册表的信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
256986 Microsoft Windows 注册表说明
概要
驱动程序验证程序包含在 Windows 2000、Windows XP 和 Windows Server 2003 中,用来提高系统的稳定性和可靠性,您可以使用此工具来解决驱动程序问题。如果存在编写错误的驱动程序(如较早的 Windows Driver Model (WDM) 驱动程序版本),Windows 内核模式组件可能会造成系统损坏或系统故障。本文介绍如何使用驱动程序验证程序,找出并解决系统中的驱动程序问题。
更多信息
本文讨论以下主题:
  • 驱动程序验证程序功能
  • I/O 验证程序
  • 驱动程序验证程序要求
  • 启用驱动程序验证程序
  • 调试驱动程序验证程序冲突
  • 驱动程序验证程序和图形驱动程序
  • 驱动程序验证程序管理器 (Verifier.exe)
  • 全局计数器
  • 池跟踪
  • 设置
  • 易变性设置
  • 命令行界面
  • 为驱动程序开发人员提供的其他信息

驱动程序验证程序功能

可通过运行 Verifier.exe 并随后重新启动计算机来使用驱动程序验证程序。要开始分析系统中的驱动程序,您不需要进行其他任何更改。

驱动程序验证程序提供以下功能。

池分配

尝试从特殊池中分配一个驱动程序的所有池配额。此驱动程序的配额是由“拒绝访问”权限分离和限定,而不是与系统的其他部分共享池配额。此功能可以确定驱动程序的池配额是否超出了其应得的份额,进而导致系统损坏和不稳定。当您启用此功能并且目标计算机拥有足够的物理和虚拟内存时,该驱动程序的所有配额将自动重定向到特殊池。

提供极限内存压力

可以为特定驱动程序提供极限内存压力,而不影响其他驱动程序(不管系统内存有多大)。使用下面的方法可以做到这一点:通知内存管理,将该驱动程序的所有可分页代码和数据以及系统页面缓冲池、代码和数据设为无效。这样,您就可以检测到错误地持有旋转锁或引发 IRQL 的驱动程序,并随后获得对分页代码或数据的访问权限。可以使用“极限内存压力”来检测一些间歇性的问题并找出原因。

参数验证

驱动程序调用的所有旋转锁、IRQL 和池分配都接受自动参数验证。这意味着检查以下各项:
  • 引发的 IRQL 确实是引发的 IRQL(当前 IRQL 低于目标 IRQL)。
  • 较低的 IRQL 确实是较低的 IRQL。
  • 释放两次旋转锁。
  • 旋转锁的获得/释放是在正确的 IRQL 下完成的。
  • 页面缓冲池分配/释放是在正确的 IRQL(APC_LEVEL 或更低)下完成的。
  • 非页面缓冲池分配/释放是在正确的 IRQL(DISPATCH_LEVEL 或更低)下完成的。
  • 没有为这些应用程序编程接口指定随机(未初始化)值。

池分配注入失败

如果驱动程序没有将池分配标记为 MUST_SUCCEED,池分配可能会被随机取消,以确保该驱动程序可以正确地处理出现的内存不足情况。

要释放的池

检查所有要释放的池,确保在此池分配中没有挂起的计时器,因为这会导致系统崩溃的原因更加难于查找。

池泄漏检测

系统自动跟踪驱动程序的所有池分配。在卸载驱动程序时,如果没有释放任何分配,就会执行错误检查。随后,您可以使用 !verifier 3 内核调试程序命令来显示未释放的所有配额。也可以在卸载前使用此命令,查看驱动程序在任一时刻的未定分配。

驱动程序卸载检查

执行驱动程序卸载检查的目的是为了找出那些已卸载但没有清除所用资源(这样就增加了在驱动程序卸载后不久即开始检查系统错误的可能性)的驱动程序。驱动程序无法删除的资源包括搁置资源的列表、挂起的延迟过程调用 (DPC)、工作线程、队列、计时器和其他资源。

I/O 验证程序

如果您使用验证程序工具或 VerifyDriverLevel 注册表项打开“I/O 验证程序”标志(有关更多信息,请参考本文“启用驱动程序验证”一节),就会打开某些 I/O 管理器验证。其中包括:
  • 通过 IoAllocateIrp 分配的所有 IRPS 都将从特殊池中分配。
  • 将在 IoCallDriver、IoCompleteRequest 和 IoFreeIrp 中进行检查以捕捉驱动程序错误信息。
  • 所有 I/O 验证程序失败都使用代码 DRIVER_VERIFIER_IOMANAGER_VIOLATION (0xC9) 进行错误检查。

驱动程序验证程序要求

唯一的要求是您必须安装 Windows 2000、Windows XP 或 Windows Server 2003。您可以在 Windows 零售版和已通过验证的版本上启用驱动程序验证程序。要了解在生产服务器上启用驱动程序验证程序管理器前需要考虑的事项,请参阅 Microsoft 知识库文章 251233。如果您安装了 Norton Antivirus,请不要启用驱动程序验证程序的“死锁检测”功能,因为 Microsoft 知识库文章 325672 中不建议这样做。

启用驱动程序验证程序

您可以使用 Verifier.exe 来启用驱动程序验证程序。Verifier.exe 包含在每个 Windows 副本中,并自动安装到 System32 文件夹中。Verifier.exe 具有命令行界面和图形用户界面 (GUI),因此,您可以指定驱动程序和相应的验证等级。您还可以实时查看驱动程序验证程序统计信息。有关其他信息,请参阅本文“驱动程序验证程序管理器”一节。

调试驱动程序验证程序冲突

内核调试程序中的 !verifier 命令以及 Verifier.exe 工具都能实时显示当前驱动程序验证程序的配置和统计信息。

所有驱动程序验证程序冲突都可能导致错误检查的执行,最常见的一些冲突包括但不限于:
  • IRQL_NOT_LESS_OR_EQUAL 0xA
  • PAGE_FAULT_IN_NONPAGED_AREA 0x50
  • PAGE_FAULT_IN_NONPAGED_AREA 0x50
  • ATTEMPTED_WRITE_TO_READONLY_MEMORY 0xBE
  • SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION 0xC1
  • DRIVER_VERIFIER_DETECTED_VIOLATION 0xC4
  • DRIVER_CAUGHT_MODIFYING_FREED_POOL 0xC6
  • TIMER_OR_DPC_INVALID 0xC7
  • DRIVER_VERIFIER_IOMANAGER_VIOLATION 0xC9

驱动程序验证程序和图形驱动程序

系统禁止 Windows 内核模式图形驱动程序(如打印机和显示器驱动程序 DLL)直接调用池入口点。相反,池分配是通过使用图形设备驱动程序接口 (DDI) 对 Win32k.sys 的回调间接完成的。例如,图形驱动程序可以回调 EngAllocMem 来显式地分配池内存。另外,其他专用回调(如 EngCreatePalette 和 EngCreateBitmap)也返回池内存。

为了给图形驱动程序提供相同种类的自动测试,在 Win32k.sys 中增加了对某些驱动程序验证程序功能的支持。但是,因为图形驱动程序比其他的内核模式驱动程序更受限制,所以它们只需要一部分驱动程序验证程序功能。具体来说,它们不需要 IRQL 检查和 I/O 验证。在不同的图形 DDI 回调中,对其他功能(也就是使用特殊池、随机取消池分配以及池跟踪)提供不同级别的支持。

下列图形 DDI 回调函数支持随机取消:
  • EngAllocMem
  • EngAllocUserMem
  • EngCreateBitmap
  • EngCreateDeviceSurface
  • EngCreateDeviceBitmap
  • EngCreatePalette
  • EngCreateClip
  • EngCreatePath
  • EngCreateWnd
  • EngCreateDriverObj
  • BRUSHOBJ_pvAllocRbrush
  • CLIPOBJ_ppoGetPath
另外,EngAllocMem 支持使用特殊池和池跟踪。

为图形驱动程序启用驱动程序验证程序的方式与其他驱动程序完全一样(有关其他信息,请参阅本文“启用驱动程序验证程序”一节)。系统将忽略不支持的标志(如 IRQL 检查)。此外,可以使用 !gdikdx.verifier 内核调试程序命令,检查当前的驱动程序验证程序状态和图形驱动程序的池跟踪。

注意:随机取消分配设置的使用仅限于进行可靠性测试。使用此设置可能导致显示错误信息,所以不应使用此设置来进行验证测试以检查图形驱动程序实现的正确性(例如,通过比较图形驱动程序输出和参考图像)。

驱动程序验证程序管理器 (Verifier.exe)

驱动程序验证程序管理器工具 (Verifier.exe) 是创建和修改驱动程序验证程序设置的首选方法,也是从驱动程序验证程序中收集统计信息的首选方法。对于每个 Windows 安装,Verifier.exe 位于 %WinDir%\System32 文件夹中。

驱动程序状态

驱动程序状态属性页提供驱动程序验证程序当前状态的图像。您可以看到验证程序所检测的驱动程序。此状态可能是下列状态之一:
  • 已加载:驱动程序当前已加载并验证。
  • 未加载:驱动程序当前未加载,但在重新启动计算机以后至少加载过一次。
  • 从未加载:驱动程序从未加载。此状态可能表明驱动程序映像文件已损坏,或者在系统中找不到指定的驱动程序名称。
可以单击列表标题,将列表按驱动程序名称或状态进行排序。在对话框的右上部分中,您可以查看当前生效的验证类型。如果不切换到手动刷新模式,则自动更新驱动程序的状态。可以使用对话框左下部分中的单选按钮修改刷新频率。也可通过单击立即更新强制更新状态。

如果启用了“特殊池”标志,并且不到 95% 的池分配进入了特殊池,则在此页上显示一条警告信息。这意味着,您需要选择更少的一组驱动程序来进行验证,或者向计算机中添加更多物理内存,以扩大池分配验证的范围。

全局计数器

全局计数器属性页显示驱动程序验证程序保存的某些计数器的当前值。如果计数器的值为零,则可能表明未启用关联的驱动程序验证程序标志。例如,如果 Other/Faults 计数器的值为 0,则表明未启用“低资源模拟”标志。您可以监视验证程序的活动,因为这些计数器的值是自动更新的(默认情况下)。您可以使用对话框左下部分中的控件组来更改刷新频率,切换到手动刷新,或者强制进行刷新。

池跟踪

此属性页显示从驱动程序验证程序中收集的更多统计信息。此页上显示的所有计数器都与验证程序的“池跟踪”标志有关。其中的大多数计数器是针对各驱动程序的计数器(例如,当前配额、当前分配的字节数等)。这意味着,您必须从顶部的组合框中选择一个驱动程序名称,以查看该特定驱动程序的计数器。

设置

可以使用此页创建并修改驱动程序验证程序的设置。这些设置保存在注册表中,要使这些设置生效,您必须重新启动计算机。您可以使用该列表查看当前安装的驱动程序。每个驱动程序可能处于下列状态之一:
  • 启用验证:当前正在对驱动程序进行验证。
  • 禁用验证:当前没有对驱动程序进行验证。
  • 启用验证(需要重新启动):仅在下次重新启动后,对驱动程序进行验证。
  • 禁用验证(需要重新启动):当前正在对驱动程序进行验证,但在下次重新启动后不对其进行验证。
可以从列表中选择一个或几个驱动程序,并使用列表下面的两个按钮来切换状态。也可以右键单击一个驱动程序名称以显示其上下文菜单,可使用该菜单来进行状态切换。

在对话框的底部,可以指定其他的驱动程序(用空格分开),以便在下次重新启动后对它们进行验证。如果要安装尚未加载的新驱动程序,通常就要使用此编辑控件。

如果将列表顶部的单选按钮组设置为当前配额,则无法使用该列表、验证不验证按钮以及编辑控件。这意味着,下次重新启动后,将验证系统中的所有驱动程序。

可以使用对话框右上部分中的复选框来设置验证类型。可以在级别 1 或级别 2 中启用 I/O 验证,级别 2 验证比级别 1 验证更强。

必须通过单击应用,保存对设置所做的任何修改。此页上还有两个其他按钮:
  • 首选设置:它选择了一些常用设置(验证所有驱动程序)。
  • 全部重置:它清除所有的驱动程序验证程序设置,因此,不对任何驱动程序进行验证。
单击应用后,必须重新启动计算机,然后这些更改才能生效。

易变性设置

可以使用此属性页立即更改驱动程序验证程序标志。只能切换某些驱动程序验证程序标志的状态,但不能更改所验证的驱动程序的列表。在更改了一些复选框的状态后,必须单击应用以使这些更改生效。这些更改将立即生效,在进行其他更改或重新启动计算机后,它们才会失效。

命令行界面

还可以从命令行运行 Verifier.exe(有关更多信息,请在命令提示符下键入 verifier.exe /?)。下面的列表中显示最常用的命令行标志:
  • verifier.exe /flags value [/iolevel 2]
    指定驱动程序验证程序标志的十进制值,并且如果可能,还要指定 I/O 验证级别(有关可用标志的列表,请在命令提示符下键入 verifier.exe /? 或参阅本文的“启用驱动程序验证程序”一节)。

    value 参数替换成下列验证位值:
    0 – 特殊池检查
    1 - 强制进行 IRQL 检查
    2 - 低资源模拟
    3 – 池跟踪
    4 - I/O 验证
    5 - 死锁检测
    6 - 增强的 I/O 验证
    7 – DMA 验证
    例如,键入以下命令:
    c:\verifier /flags 3 /iolevel 2
    注意:默认的 I/O 验证级别是 1。如果在标志中没有设置 I/O 验证位,则忽略该值。
  • verifier.exe /all
    验证系统中的所有驱动程序。
  • verifier.exe /volatile /flags value
    立即更改验证程序标志。
  • verifier.exe /reset
    清除当前的所有驱动程序验证程序设置。
  • verifier /query
    将当前的驱动程序验证程序状态和计数器转储到标准输出。
  • verifier.exe /log LOG_FILE_NAME [/interval seconds]
    将驱动程序验证程序状态和计数器记录到日志文件中(其中 seconds 是指定的时间段)。

为驱动程序开发人员提供的其他信息

以下部分提供了有关驱动程序验证程序设置的其他信息,驱动程序开发人员可能会非常感兴趣。通常,这些设置不是 IT 专业人员所必需的设置。
警告:注册表编辑器使用不当可能导致严重问题,可能需要重新安装操作系统。Microsoft 不能保证您可以解决因注册表编辑器使用不当而导致的问题。使用注册表编辑器需要您自担风险。
若要通过编辑注册表来启用驱动程序验证程序,请按照下列步骤操作:
  1. 启动注册表编辑器 (Regedt32)。
  2. 找到下面的注册表项:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\VerifyDrivers
  3. 编辑 REG_SZ 项。
将 REG_SZ 项设置为要测试的驱动程序的名称(不区分大小写)。可以指定多个驱动程序,但只能使用一个驱动程序。这样,您就可以确保可用系统资源不会过早地枯竭。资源过早枯竭不会导致任何系统可靠性问题,但是可能导致跳过检查某些驱动程序。

下面的列表显示了 REG_SZ 项值的示例:
  • Ntfs.sys
  • Win32k.sys ftdisk.sys
  • *.sys
可以在下面的注册表项中指定驱动程序验证的级别:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\VerifyDriverLevel
下面的列表显示了此项的位字段值。您可以自由组合这些值:
  • 0x01:尝试满足特殊池的所有分配。
  • 0x02:将内存压力应用于此驱动程序,以验证访问分页代码和数据时使用 IRQL 的情况。
  • 0x04:随机取消各种池分配请求。在系统启动后,只有在出现的问题必须得到处理时,才会执行此操作。
  • 0x08:启用池分配跟踪。驱动程序卸载或系统执行错误检查前,必须释放每个分配。
  • 0x10:启用 I/O 验证程序。
注意:如果该项不存在,或者未指定驱动程序的验证级别,则默认值为 3。如果在验证程序实用工具中使用首选设置,则默认值为 0x1B。要跟踪内存泄漏,请尝试使用值 0xB。通过单击选中“首选设置”复选框,并单击清除“I/O 验证”复选框,可以非常方便地获取此值。
bugcheck
属性

文章 ID:244617 - 上次审阅时间:08/12/2005 13:33:00 - 修订版本: 5.1

Microsoft Windows 2000 Server, Microsoft Windows 2000 Advanced Server, Microsoft Windows 2000 Professional Edition, Microsoft Windows 2000 Datacenter Server, Microsoft Windows XP Home Edition, Microsoft Windows XP Professional Edition, Microsoft Windows Server 2003 Datacenter Edition, Microsoft Windows Server 2003 Enterprise Edition, Microsoft Windows Server 2003 Standard Edition

  • kbhowto kbenv kbprogramming KB244617
反馈