池跟踪

池跟踪监视驱动程序进行的内存分配。 卸载驱动程序时,驱动程序验证程序确保已释放驱动程序所做的所有分配。

未释放的内存分配 (也称为 内存泄漏) 是操作系统性能降低的常见原因。 它们可能会使系统池碎片化,并最终导致系统崩溃。

当此选项处于活动状态时,如果驱动程序在未释放其所有分配的情况下卸载,驱动程序验证程序将发出参数 1 等于0x62) 的 bug 检查 0xC4 (。

如果驱动程序验证程序发出此 bug 检查,参数 1 等于 0x51、0x52、0x53、0x54 或 0x59,则驱动程序已写入其分配之外的内存。 在这种情况下,应启用 特殊池 功能来查找错误的来源。

有关 bug 检查参数的列表,请参阅 bug 检查0xC4 (DRIVER_VERIFIER_DETECTED_VIOLATION) 。

从 Windows Vista 开始,启用“池跟踪”选项还会启用锁定页面的跟踪。 当此选项处于活动状态时,如果驱动程序在 I/O 操作后无法释放锁定的页面,驱动程序验证程序将发出 bug 检查0xCB (DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS) 。

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

在 Windows 7 及更高版本的 Windows 操作系统中,激活池跟踪时,驱动程序验证程序可以检测在空闲进程上下文中分配具有 配额 的内核池内存的尝试。 此类尝试通常意味着驱动程序正在从 DPC 例程分配内存。 DPC 例程的线程或进程上下文不可靠,因此尝试向该进程收取配额不正确。

监视池跟踪

对于要验证的每个驱动程序,可以单独监视内存池分配统计信息。 这些统计信息可由驱动程序验证程序管理器、Verifier.exe命令行或日志文件显示。 有关详细信息 ,请参阅监视单个计数器

内核调试器扩展 !verifier 0x3 可用于在驱动程序卸载后查找未完成的内存分配,或者在驱动程序运行时跟踪当前分配。 此扩展还显示池标记、池大小以及每个分配的分配器的地址。 有关调试器扩展的信息,请参阅 Windows 调试

来自 DPC 例程的池配额费用

内核驱动程序可以调用 ExAllocatePoolWithQuotaTag 来分配内核池内存,并按分配给当前进程的池配额的字节数收费。 驱动程序通常对与来自应用程序的请求直接相关的内存分配使用配额。

延迟过程调用 (DPC) 例程可以在任何进程的上下文中运行。 因此,从 DPC 例程收取配额会向随机进程收费。 更糟的是,当 DPC 例程在空闲进程的上下文中运行时,这种情况可能会导致内存损坏或系统崩溃。

从 Windows 7 开始,驱动程序验证程序检测来自 DPC 例程的 ExAllocatePoolWithQuotaTag 调用。

激活此选项

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

  • 在命令行

    在命令行中,池跟踪选项由 位 3 (0x8) 表示。 若要激活池跟踪,请使用标志值0x8或向标志值添加0x8。 例如:

    verifier /flags 0x8 /driver MyDriver.sys
    

    下次启动后,该功能将处于活动状态。

    在 Windows Vista 和更高版本的 Windows 上,还可以通过将 /volatile 参数添加到 命令来激活和停用池跟踪,而无需重新启动计算机。 例如:

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

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

    标准设置中还包含池跟踪功能。 例如:

    verifier /standard /driver MyDriver.sys
    
  • 使用驱动程序验证程序管理器

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

    标准设置中还包含池跟踪功能。 若要使用此功能,请在驱动程序验证程序管理器中,单击“ 创建标准设置”。