资源不足模拟

当 Windows 8.1) 中称为“随机化低资源模拟”的“低资源模拟”选项 (处于活动状态时,驱动程序验证程序会使驱动程序的内存分配的随机实例失败,如果驱动程序在内存不足的计算机上运行,则可能会发生此情况。 这将测试驱动程序对内存不足和其他资源不足情况做出正确响应的能力。

资源不足模拟测试无法通过调用多个不同函数(包括 ExAllocatePoolWithXXXMmGetSystemAddressForMdlSafeMmProbeAndLockPagesMmMapLockedPagesSpecifyCacheMmMapIoSpace)请求的分配。

从 Windows Vista 开始,低资源模拟测试还会将错误注入 IoAllocateIrpIoAllocateMdlIoAllocateWorkItemIoAllocateErrorLogEntryMmAllocateContiguousMemoryMmAllocateContiguousMemorySpecifyCacheMmAllocatePagesForMdlMmAllocatePagesForMdlEx。 此外,从 Windows Vista 开始,启用“低资源模拟”后,调用将 Alertable 参数设置为 TRUEKeWaitForMultipleObjectsKeWaitForSingleObject 可在非特权进程的上下文中运行时返回STATUS_ALERTED。 这会模拟来自同一非特权应用程序中另一个线程的可能线程警报。

低资源模拟测试还会将错误注入到以下 GDI 函数中: EngAllocMemEngAllocUserMemEngCreateBitmapEngCreateDeviceSurfaceEngCreateDeviceBitmapEngCreatePaletteEngCreateClipEngCreatePathEngCreateWndEngCreateDriverObjBRUSHOBJ_pvAllocRbrushCLIPOBJ_ppoGetPath

在 Windows 7 及更高版本的 Windows 操作系统中,“低资源模拟”选项支持使用以下内核 API 分配的内存:

从Windows 8.1开始,“低资源模拟”选项也未能通过调用 MmAllocateNodePagesForMdlEx 请求的分配。 此外,对于某些函数,驱动程序验证程序现在使用随机模式填充分配的内存。 但仅在函数返回未初始化内存的情况下。 这些函数包括:

用于低资源模拟的自定义设置

在 Windows Vista 和更高版本的 Windows 上,可以指定以下自定义设置。

  • 给定分配失败的概率。 默认值为 6%。

  • 受影响的应用程序。 此设置将注入失败的分配限制为指定的应用程序。 默认情况下,所有分配都会受到影响。

  • 受影响的池标记 。 此设置将注入的错误限制为具有指定池标记的分配。 默认情况下,所有分配都会受到影响。

  • 分配失败之前,) 延迟 (分钟。 此延迟允许系统在注入故障之前启动和稳定。 默认值为 8 分钟。

在 Windows Vista 之前的操作系统上,无法自定义这些设置。 操作系统使用默认值。

无需重启的低资源模拟

可以在 Windows 2000 及更高版本的 Windows 上激活低资源模拟,而无需使用 /volatile 参数重启计算机。 设置会立即生效,但如果关闭或重启计算机,这些设置将丢失。

还可以通过省略 /volatile 参数将低资源模拟设置存储在注册表中。 这些设置仅在重启计算机时有效,但在你更改这些设置之前仍有效。

激活此选项

可以使用驱动程序验证程序管理器或Verifier.exe命令行为一个或多个驱动程序激活低资源模拟选项。 有关详细信息,请参阅 选择驱动程序验证程序选项

  • 在命令行

    在命令行中,“低资源模拟”选项由 位 2 (0x4) 表示。 若要激活资源不足模拟,请使用标志值0x4或向标志值添加0x4。 例如:

    verifier /flags 0x4 /driver MyDriver.sys
    

    选项将在下一次启动后处于活动状态。

    在 Windows Vista 和更高版本的 Windows 上,可以使用 /faults 参数或 0x4 的标志值来激活低资源模拟。 若要修改低资源模拟的设置,必须使用 /faults。 例如:

    verifier /faults /driver MyDriver.sys
    

    在 Windows 2000 及更高版本的 Windows 上,还可以通过将 /volatile 参数添加到 命令来激活和停用资源不足模拟,而无需重启计算机。 例如:

    verifier /volatile /flags 0x4 /adddriver MyDriver.sys
    

    此设置会立即生效,但在关闭或重启计算机时会丢失。 有关详细信息,请参阅 使用易失性设置

    在 Windows Vista 上,可以使用 /faults 参数通过 /volatile 参数表示低资源模拟,以表示无需重新启动即可生效的设置。 将显示设置更改。 例如:

    0>  verifier /volatile /faults /adddriver MyDriver.sys
    New Low Resources Simulation options:
    
    - Use default fault injection probability.
    - Allocations using any pool tag can be failed.
    - Simulate low resources conditions in any application.
    
    The new settings are in effect until you restart this computer
    or change them again.
    
  • 使用驱动程序验证程序管理器

    1. 启动驱动程序验证程序管理器。 在命令提示符窗口中键入 验证程序
    2. 选择 “为代码开发人员创建自定义设置 () ”,然后单击“ 下一步”。
    3. 从完整列表中选择“选择单个设置”。
    4. 选择 “资源不足模拟”。

自定义 Windows Vista 及更高版本 (设置)

从 Windows Vista 开始,你可以更改“低资源模拟”选项的延迟、概率、应用程序和池标记属性的默认设置。 可以使用驱动程序验证程序管理器或Verifier.exe命令行更改这些设置。 有关详细信息,请参阅 选择驱动程序验证程序选项

在命令行中,这些设置的语法如下所示:

验证程序 [/volatile] /faults[Probability|PoolTags|Applications|DelayMins][/driver|DriverList]

注意 自定义设置参数必须按显示顺序显示。 如果省略某个值,请键入引号来保留其位置。

子参数

  • /faults

    在驱动程序验证程序中启用“资源不足模拟”选项。 (不能将 /flags 0x4与自定义设置子参数一起使用。)

  • 概率

    指定驱动程序验证程序在给定分配中失败的概率。 键入十进制或十六进制格式的数字 () 表示驱动程序验证程序分配失败的几率(以 10,000 为单位)。 默认值 600 表示 600/10000 或 6%。

  • PoolTags

    限制驱动程序验证程序可能无法使用指定池标记进行分配的分配。 可以使用通配符 (*) 来表示多个池标记。 若要列出多个池标记,请用空格分隔标记。 默认情况下,所有分配都可能失败。

  • 应用程序

    限制驱动程序验证程序无法为指定程序分配的分配。 键入可执行文件的名称。 若要列出程序,请用空格分隔程序名称。 默认情况下,所有分配都可能失败。

  • DelayMins

    指定启动后的分钟数,在此期间驱动程序验证程序不会有意使任何分配失败。 在测试开始之前,可以在这段此延迟时间内加载驱动程序并稳定系统。 以十进制或十六进制格式键入数字 () 。 默认值为 8 (分钟) 。

例如,以下命令启用低资源模拟,其概率为 10% (1000/10000) ,池标记 Tag1 和 Fred 以及应用程序Notepad.exe延迟 5 分钟。

verifier /faults 1000 "Tag1 Fred" Notepad.exe 5

以下命令使用默认值启用低资源模拟,但将延迟延长到 10 分钟。

verifier /faults "" "" "" 0xa

使用驱动程序验证程序管理器

  1. 启动驱动程序验证程序管理器。 在命令提示符窗口中键入 验证程序

  2. 选择“ 为代码开发人员创建自定义设置 () ”,然后单击“ 下一步”。

  3. 从完整列表中选择“选择单个设置”。

  4. 选择“ 资源不足模拟”,然后单击“ 下一步”。

  5. 根据需要更改延迟、概率、应用程序和池标记属性的设置。

查看结果

可以通过显示驱动程序验证程序 故障注入 全局计数器来监视驱动程序验证程序有意失败资源分配的次数。 此计数器显示自上次启动以来驱动程序验证程序故意失败的资源分配总数。

可以在驱动程序验证程序日志文件 (/log) 、命令行 (/query) 或驱动程序验证程序管理器中查看此计数器。 在 Windows 2000 中,若要查看全局计数器,请选择“ 全局计数器 ”选项卡。在更高版本的 Windows 中,选择“ 显示有关当前已验证的驱动程序任务的信息 ”,然后按 “下一步” 两次。 有关详细信息,请参阅 监视全局计数器

还可以显示有意失败的分配数和总分配数, (使用 !verifier 调试器扩展计算) 概率。 以下示例显示了 !verifier 输出的示例。

在此示例中, 注入随机资源不足 API 失败 指示已启用资源不足模拟。 资源分配失败故意 表示有意失败的分配数, 尝试的池分配 表示分配总数。

!verifier

Verify Level 5 ... enabled options are:
        Special pool
        Inject random low-resource API failures

Summary of All Verifier Statistics

RaiseIrqls                             0x2c671f
AcquireSpinLocks                       0xca1a02
Synch Executions                       0x10a623
Trims                                  0x0

Pool Allocations Attempted             0x862e0e
Pool Allocations Succeeded             0x8626e3
Pool Allocations Succeeded SpecialPool 0x768060
Pool Allocations With NO TAG           0x0
Pool Allocations Failed                0x34f
Resource Allocations Failed Deliberately   0x3f5

若要显示驱动程序验证程序最近失败的分配的堆栈跟踪,请在内核调试 器中使用 !verifier 4

以下示例显示了 !verifier 4 的输出示例。 默认情况下, !verifier 4 显示四个最近失败的分配中的堆栈跟踪,但你可以使用其 Quantity 参数来增加显示的堆栈跟踪数。 例如,!verifier 0x80 显示最近失败的 128 个分配。

在此示例中,请注意,验证程序截获并替换了驱动程序对 ExAllocatePoolWithTag 的调用。 驱动程序崩溃的最常见原因之一是驱动程序尝试分配内存,然后使用分配函数返回的指针,然后再验证它是否为 NULL

kd> !verifier 4
Resource fault injection history:
Tracker @ 8354A000 (# entries: 80, size: 80, depth: 8)

Entry @ 8354B258 (index 75)

    Thread: C2638220

    816760CB nt!VerifierExAllocatePoolWithTag+0x49
    A4720443 win32k!bDeleteAllFlEntry+0x15d
    A4720AB0 win32k!GreEnableEUDC+0x70
    A47218FA win32k!CleanUpEUDC+0x37
    A473998E win32k!GdiMultiUserFontCleanup+0x5
    815AEACC nt!MiDereferenceSession+0x74
    8146D3B4 nt!MmCleanProcessAddressSpace+0x112
    815DF739 nt!PspExitThread+0x603

Entry @ 8354B230 (index 74)

    Thread: 8436D770

    816760CB nt!VerifierExAllocatePoolWithTag+0x49
    A462141C win32k!Win32AllocPool+0x13
    A4725F94 win32k!StubGdiAlloc+0x10

低资源模拟测试的经验表明,大多数驱动程序崩溃是由最近失败的分配引起的。 在上面的示例中,崩溃位于 win32k!GreEnableEUDC。 检查分配路径中的代码,找出崩溃的原因。

有关 !verifier 的信息,请参阅 Windows 调试工具 文档。

若要在命令行中查看注册表中的设置,请使用 /querysettings 选项。 例如:

C:\>verifier /querysettings
Special pool: Disabled
Pool tracking: Disabled
Force IRQL checking: Disabled
I/O verification: Disabled
Enhanced I/O verification: Disabled
Deadlock detection: Disabled
DMA checking: Disabled
Security checks: Disabled
Force pending I/O requests: Disabled
Low resources simulation: Enabled
IRP Logging: Disabled
Miscellaneous checks: Disabled

Low Resources Simulation options:

- Fault injection probability: 1/10000.
- Fail only allocations using pool tags: Tag1 Tag2.
- Simulate low resources conditions only in applications: test1.exe test2.exe.
- Boot time delay: 2 minutes.

Verified drivers:

blah.sys