在Windows中测量设备驱动程序的内存使用情况

8

我该如何确定每个设备驱动程序消耗了多少内存? 我假设这可以通过一些Win32或.NET API来完成,但我只是无法确定使用哪个API。

2个回答

11

Windows 使用池标记(pool tags)跟踪设备驱动程序的内存使用情况。如果您知道有关该驱动程序传递给 ExAllocatePoolWithTag 的池标记,则可以使用工具(如 Windows Driver Kit 中的 poolmon、OSR 公司的 PoolTag 或调试工具中的 WinDbg (或 KD) )来跟踪其内存使用情况。

需要注意的是,设备驱动程序可能会调用内核 API 间接地分配内存。例如,调用 IoAllocateMdl 将导致 Windows I/O 管理器分配存储器描述符列表的内存,并使用由 Windows I/O 管理器指定的不同的池标记进行分配。因此,代表多个设备驱动程序执行的分配可能都使用相同的池标记。

如果您正在尝试确定哪个驱动程序存在内存泄漏问题,请使用 poolmon/PoolTag/WinDbg/KD 识别泄漏的池标记。然后,将内核调试器(WinDbg 或 KD)附加到系统,并将变量 nt!poolhittag 设置为泄漏的池标记。下一次使用该池标记调用 ExAllocatePoolWithTag 分配内存时,系统会中断进入内核调试器,然后您可以查看调用堆栈以确定执行分配操作的驱动程序。有关详细信息,请参见 使用内核调试器查找内核模式内存泄漏


这是正确的答案。如果您想跟踪单个驱动程序,程序“verifier”可能会更容易地帮助您,只需在命令提示符下调用“verifier.exe”。使用此工具,您可以跟踪单个驱动程序。 - Christopher

1

我知道这并不容易。以下是一些与问题密切相关的起点:

您可以使用 VirtualQueryEx来确定PE文件、堆等使用的内存,但这可能无法令您满意。 这里有一个提供虚拟内存映射视图的程序。这应该可以回答设备驱动程序的图像大小。

更大的难度在于确定由分配它的代码动态分配的内存如何标记。最好的方法是使用类似 detours的工具来跟踪动态内存分配,并沿着堆栈行走以确定原始分配者。 最后,您希望为设备驱动程序完成此操作使得问题更加复杂。我怀疑detours是否适用于设备驱动程序(尽管我不确定)。 我知道从设备驱动程序中行走堆栈是极其困难的。

你也可以从SysInternals套件中的ProcExp获取所需的数据。运行它,进入“系统”,进入“查看/显示下窗格”,启用Dll。然后右键单击列标题并添加工作集的列,例如“WS Total”。我不确定这样做是否能正确标记它们的内存。在我的电脑上,它会给设备驱动程序映像大小,但是在工作集列中只有0K。我认为procexp没有回答是解决这个问题不容易的证据。

祝你好运。


太棒了!Process Explorer再次发挥了作用。虽然工作集数据只是0,但可以获取物理内存基地址和映射大小,这是朝着正确方向迈出的一大步。 - Justin R.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接