使用驱动程序验证程序识别高级Windows驱动程序的问题

自 2000 以来,驱动程序验证程序工具Windows每个Windows版本中。 它用于检测和解决许多已知的驱动程序问题,这些问题会导致系统损坏、故障或其他不可预知的行为。 本文介绍如何使用驱动程序验证程序隔离和排查系统中驱动程序的问题。

适用于:  Windows Server 2012 Foundation、Windows Server 2012 Essentials、Windows Server 2012 Standard、Windows Server 2012 Datacenter
原始 KB 编号:   244617

驱动程序验证程序功能

若要使用驱动程序验证程序,请Verifier.exe,然后重新启动计算机。 你不必进行任何其他更改来开始分析系统驱动程序。 您的用户帐户需要管理员权限才能运行Verifier.exe。

驱动程序验证程序可以检查驱动程序行为的许多不同方面。 这些功能分为使用标志启用的选项或设置。 (驱动程序验证程序文档中的术语选项、设置和标志通常可互换。 它们表示类似的概念。)

有关每个标志的详细信息,请参阅驱动程序 验证程序选项和规则类

标准选项

以下选项共同表示系统中所有驱动程序不应违反的规则。 当你选择在驱动程序验证程序 GUI 中启用标准设置,或者当你使用命令行配置驱动程序验证程序时指定开关时, /standard 这些选项将启用。

自动检查

无论选择了哪些选项,这些检查始终在要验证的驱动程序上完成。

自动检查示例:

  • IRQL 检查
    • 引发 IRQL (意味着当前 IRQL 小于目标 IRQL) 。
    • 降低的 IRQL (意味着当前 IRQL 大于目标 IRQL) 。
  • SpinLocks:
    • 双释放旋转锁。
    • 在相应的 IRQL 进行旋转锁定获取/发布。
  • 内存分配:
    • 分页池分配/释放在正确的 IRQL (APC_LEVEL或) 。
    • 非分页池分配/释放在正确的 IRQL (DISPATCH_LEVEL或) 。
    • 对于这些 (API) 应用程序编程接口未指定任何 (未初始化) 。
    • 释放的分配不指向活动的计时器对象。
  • 驱动程序卸载检查:
    • 验证驱动程序在卸载时没有挂起的操作,例如挂起的 DPC 或工作线程。
  • 其他驱动程序行为:
    • 不正确地切换线程堆栈。
    • 尝试调用 IRQL 中的 KeWaitXxx >= DISPATCH_LEVEL。
    • 取消引用已具有引用计数 0 的对象。

特殊池

当此选项处于活动状态时,驱动程序验证程序从特殊池分配驱动程序的内存请求大部分。 监视此特殊池的内存溢出、内存不足和释放后访问的内存。

强制 IRQL 检查

当此选项处于活动状态时,驱动程序验证程序会通过使可分页代码无效对驱动程序施加极端内存压力。 如果驱动程序尝试访问错误 IRQL 或持有旋转锁的分页内存,驱动程序验证程序将检测到此行为。

池跟踪

当此选项处于活动状态时,驱动程序验证程序会检查驱动程序在卸载时是否释放了它的所有内存分配。 它显示内存泄漏。

I/O 验证

当此选项处于活动状态时,驱动程序验证程序从特殊池分配驱动程序的 IAP,并监视驱动程序的 I/O 处理。 它检测到 I/O 例程的使用非法或不一致。

启用 I/O 验证程序时:

  • 通过 IoAllocateIrp 分配的所有 IAP 均从特殊池分配(如果可用)。
  • 在 IoCallDriver、IoCompleteRequest 和 IoFreeIrp 中进行检查,以捕获驱动程序错误消息。
  • 使用代码检查程序的所有 I/O 验证程序DRIVER_VERIFIER_IOMANAGER_VIOLATION (0xC9) 。

备注

在 Windows 7 和更高版本的 Windows 操作系统中,增强 I/O 验证的所有功能均包含在 I/O 验证中,并且不再可用,也无需在驱动程序验证程序管理器或命令行中选择增强的 I/O 验证选项。

死锁检测

当此选项处于活动状态时,驱动程序验证程序将监视驱动程序对旋转锁、互斥和快速互斥的使用。 它检测驱动程序的代码是否可能在某些时候导致死锁。

增强的 I/O 验证

当此选项处于活动状态时,驱动程序验证程序将监视多个 I/O 管理器例程的调用,并执行 PnP IR、电源 IAP 和 WMI IR 的压力测试。

备注

在 Windows 7 及更高版本中,增强型 I/O 验证的所有功能均包含在 I/O 验证中。 驱动程序验证程序管理器或命令行中不再提供此选项或不再需要此选项。

DMA 验证

当此选项处于活动状态时,驱动程序验证程序将监视驱动程序对 DMA 例程的使用。 它检测到 DMA 缓冲区、适配器和映射寄存器的不正确使用。

安全检查

当此选项处于活动状态时,驱动程序验证程序将查找可能导致安全漏洞的常见错误,例如内核模式例程对用户模式地址的引用。

杂项检查

当此选项处于活动状态时,驱动程序验证程序将查找驱动程序崩溃的常见原因,例如释放的内存错误处理。

DDI 合规性检查

当此选项处于活动状态时,驱动程序验证程序会应用一组设备驱动程序接口 (DDI) 规则,这些规则检查驱动程序和操作系统的内核接口之间的正确交互。

DDI 合规性检查选项是通过使用内核模式库实现的,称为VerifierExt.sys。 如果发现违反 DDI 合规性检查规则之一,VerifierExt.sys将调用模块进行系统 Bug 检查。

其他选项

这些选项专为特定方案测试设计,或用于将故障或延迟注入特定 DDI 例程以模拟极端压力情况的选项。

驱动程序验证程序要求

唯一的要求是必须安装Windows Server 2012。 你可以同时在零售版本和已选中版本的驱动程序验证程序Windows。 如果已安装了"如果安装了 Driver Antivirus",则不要启用驱动程序验证程序死锁检测。

启用驱动程序验证程序

可以通过使用驱动程序验证程序来启用Verifier.exe。 Verifier.exe副本中都包含Windows。 它会自动安装到 System32 文件夹中。 Verifier.exe具有命令行和图形用户界面, (GUI) 接口,因此你可以指定驱动程序和适当的验证级别。 还可以实时查看驱动程序验证程序统计信息。 有关详细信息,请参阅驱动程序验证 程序管理器 (Verifier.exe) 部分。

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

如果驱动程序验证程序检测到冲突,则标准行为是对系统进行 bug 检查,以提供有关调试问题的最可能信息。 一旦发生 Bug 检查,连接到调试程序的系统将停止。

所有驱动程序验证程序违反都会导致 bug 检查,最常见的错误 (尽管不一定全部) 为:

  • 0xC1:SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION
  • 0xC4:DRIVER_VERIFIER_DETECTED_VIOLATION
  • 0xC6: DRIVER_CAUGHT_MODIFYING_FREED_POOL
  • 0xC9:DRIVER_VERIFIER_IOMANAGER_VIOLATION
  • 0xD6:DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION
  • 0xE6:DRIVER_VERIFIER_DMA_VIOLATION

!analyze -v 是启动新的调试会话时使用的最佳命令。 此命令将返回有用的信息并尝试定位出错的驱动程序。

特定于驱动程序验证程序调试器扩展:

  • !verifier 将转储捕获的驱动程序验证程序统计信息。 !verifier -? 将显示所有可用选项。
  • !deadlock 转储与锁定或由死锁检测跟踪的对象有关的信息。 !deadlock -? 将显示所有可用选项。
  • !iovirp [address] 将转储与 I/O 验证程序跟踪的 IRP 有关的信息。
  • !ruleinfo [RuleID] 将转储与违反 (RuleID 的 DDI 合规性检查规则相关的信息始终为 bug 检查的第一个参数,所有 DDI 合规性检查规则 ID 都为 0x200nn) 。

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

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) 是创建和修改驱动程序验证程序设置以及从驱动程序验证程序收集统计信息的首选方法。 Verifier.exe每个安装都位于 %WinDir%\System32 文件夹中Windows文件夹。

驱动程序验证程序管理器是配置驱动程序验证程序Windows中包含的 GUI。 在没有任何其他命令行开关的情况下,verifier.exe驱动程序验证程序管理器。 只要包含开关,就会使用基于命令行的实用工具版本。

有关配置驱动程序验证程序的帮助,请 verifier.exe /? 从管理员 CMD 窗口运行。

驱动程序状态

驱动程序状态属性页为你提供驱动程序验证程序的当前状态的图像。 你可以看到验证程序检测到的驱动程序。 状态可以是下列值之一:

  • 已加载:驱动程序当前已加载并验证。
  • 已卸载:驱动程序当前未加载,但自重启计算机后至少已加载一次。
  • 从不加载:从未加载过驱动程序。 此状态可以指示驱动程序映像文件已损坏,或者你指定了系统中缺少的驱动程序名称。

选择列表标头以按驱动程序名称或状态对列表进行排序。 在对话框的右上方区域,可以查看当前有效验证类型。 如果不切换到手动刷新模式,驱动程序的状态将自动更新。 可以使用对话框左下角区域中的单选按钮修改刷新频率。 若要强制更新状态,请选择"现在 更新"。

如果启用"特殊池"标志,并且少于 95% 的池分配已进入特殊池,则此页上将显示一条警告消息。 这意味着你需要选择一组较小的驱动程序进行验证,或向计算机添加更多物理内存,以便更好地覆盖池分配验证。

全局计数器

此属性页显示驱动程序验证程序维护的一些计数器的当前值。 计数器的零值可以指示未启用关联的驱动程序验证程序标志。 例如,"其他/错误"计数器的值为 0 表示未启用低资源模拟标志。 您可以监视验证程序的活动,因为默认情况下计数器的值会自动更新。 可以使用对话框左下角的一组控件更改刷新频率、切换到手动刷新或强制刷新。

池跟踪

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

设置

可以使用此页面创建和修改驱动程序验证程序设置。 设置保存在注册表中,必须重新启动计算机,设置才能生效。 可以使用列表查看当前安装的驱动程序。 每个驱动程序都可以具有以下状态之一:

  • 验证已启用:当前已验证驱动程序。
  • 验证已禁用:当前未验证驱动程序。
  • Verify Enabled (Reboot Needed) : The driver is verified only after the next restart.
  • Verify Disabled (Reboot Needed) : The driver is currently verified but isn't verified after the next restart.

你可以从列表中选择一个或多个驱动程序,然后使用列表下的两个按钮切换状态。 还可以右键单击驱动程序名称以显示上下文菜单,从而允许你执行状态切换。

在对话框底部,你可以指定更多驱动程序, (空格分隔) 下一次重启后要验证的驱动程序。 当你想要安装尚未加载的新驱动程序时,通常使用此编辑控件。

如果列表顶部的单选按钮组设置为"验证所有驱动程序",则列表和"验证"和"不验证"按钮和编辑控件将不可用。 这意味着,在下次重启后,将验证系统内的所有驱动程序。

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

通过选择"应用"保存对设置的任何 修改。 此页中还有两个按钮:

  • 首选设置:它选择一些常用的设置 (所有驱动程序都经过) 。
  • 全部重置:它将清除所有驱动程序验证程序设置,以便不验证驱动程序。

选择" 应用" 后,必须重新启动计算机,更改才能生效。

可变设置

可以使用此属性页立即更改驱动程序验证程序标志。 你只能切换某些驱动程序验证程序标志的状态。 你无法更改正在验证的驱动程序列表。 更改某些复选框的状态后,选择" 应用 "使更改生效。 更改会立即生效。 它们一直持续到您进行其他更改,或直到重新启动计算机。

命令行接口

您还可以从命令行Verifier.exe运行 (,有关详细信息,请键入 verifier.exe /? 在命令提示符下) 。 命令行上可以使用多个开关,例如:

Verifier.exe /flags 0x209BB /driver MyDriver1.sys MyFilterDriver1.sys

以下列表显示了最常用的命令行标志:

配置选项 (标记)

  • verifier.exe /flags

    Value 是一个十六 (0x 前缀,) 表示要启用的标志的组合值。 每个标志的值都显示在输出 verifier /? 中。

    标准标志:

    0x00000000:自动检查
    0x00000001:特殊池
    0x00000002:强制进行 IRQL 检查
    0x00000008:池跟踪
    0x00000010:I/O 验证
    0x00000020:死锁检测
    0x00000080:DMA 检查
    0x00000100:安全检查
    0x00000800:杂项检查
    0x00020000:DDI 合规性检查

    更多标志:

    0x00000004:随机化低资源模拟
    0x00000040:仅 Vista (增强的 I/O 验证)
    0x00000200:强制挂起 I/O 请求
    0x00000400:IRP 日志记录
    0x00002000:固定 MDL 堆栈检查
    0x00004000:driver0x00008000 的固定 MDL 检查:Power framework 延迟模糊处理

    例如,若要仅启用特殊池、I/O 验证和杂项检查:

    verifier.exe /flags 0x811
    

    若要启用所有标准设置 (两个示例均) :

    verifier.exe /standard
    
    verifier.exe /flags 0x209BB
    
  • 配置要验证的驱动程序

    verifier.exe /driver driver1.sys [driver2.sys driver3.sys ...]
    

    此命令指定要验证的特定驱动程序。 在以空格分隔的列表中提供其他驱动程序。

    verifier.exe /all
    

    此命令验证系统内的所有驱动程序。

  • 使用可变模式配置

    verifier.exe /volatile /flags *value /adddriver MyDriver1.sys*
    

    此命令会立即更改验证程序标志,MyDriver1.sys进行验证。

  • 查询当前验证程序统计信息

    verifier /query
    

    将当前驱动程序验证程序状态和计数器转储到标准输出。

  • 查询当前验证程序设置

    verifier /querysettings
    

    将当前驱动程序验证程序设置转储到标准输出。

  • 清除验证程序设置

    verifier.exe /reset
    

    此命令将清除所有当前驱动程序验证程序设置。

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

以下各节介绍驱动程序开发人员可能感兴趣的驱动程序验证程序设置的更多详细信息。 IT 专业人员通常不需要这些设置。

重要

此部分(或称方法或任务)介绍了修改注册表的步骤。 但是,注册表修改不当可能会出现严重问题。 因此,请务必严格按照这些步骤操作。 为了加强保护,应先备份注册表,再进行修改。 如果出现问题,可以还原注册表。 若要详细了解如何备份和还原注册表,请参阅如何在 Windows 中备份和还原注册表

若要通过编辑注册表启用驱动程序验证程序,请按照以下步骤操作:

  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

键的值是一个 DWORD,表示已启用的所有标志的集合。