内核内存泄露检查

来源:互联网 发布:数据流程图,符号表示 编辑:程序博客网 时间:2024/06/15 04:32
作 者: correy
时 间: 2012-07-29,11:33:30
链 接: http://bbs.pediy.com/showthread.php?t=154015

前言:内核内存泄露,对高手来说是小事一桩,轻而易举就能查到的,
      但是对于没有接触过这的,要熟悉它,可能需要一段时间,比如我。
      写的不好的地方,请多多指正。

内核内存的影响是很大的,特别是在服务器上,具体的看下面的案例。

检查内核内存池泄露的工具有:
poolmon.exe微软的命令行工具,在wdk里面。
Pooltag.exe,osr的图形界面工具。
Gflags.exe,windbg里面有。另一种办法是修改注册表。
Pooltag.txt,windbg里面的。//这个很有用。
Verifier.exe,这个是系统自带的。//这个暂时我没有用到。

步骤如下:
首先确保poolmon工具可以使用:winddows 2003及以后的好像不用设置。

方法一:使用Gflags.exe,具体的步骤如下:
1.单击开始,单击运行,键入gflags.exe,然后单击确定
2.选择启用池标记
3.单击应用,然后单击确定
4.重新启动计算机。

方法二:或者使用注册表修改,修改办法如下:
1.运行注册表编辑器。
2.在注册表中找到以下项:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager
3.记下的值的GlobalFlag,或保存Session Manager键。
4.双击右窗格中的GlobalFlag值。
5.将值更改为0x00000400的十六进制。
注意当您添加全局标志值 0x00000400 时,它只显示为正在 0x400 后它将被添加。一定要添加前导零的所有或某些 Poolmon 信息将不会显示在输出屏幕。
重新启动计算机。

Poolmon.exe是命令行的,功能强大,不易使用。简要的说明几个使用办法:
P-排序标记列表中的通过分页,非分页,或混合。
B-标记按最大字节使用情况。M-标记按最大字节分配。
T 按标记名称的字母顺序排序-标记。
E-显示分页,跨底部未分页的总数。循环。
A-标记按分配大小。
F-按标记"释放"。
S-按标记的 allocs 的差异,并释放。
E-显示分页,跨底部未分页的总数。循环。
Q-退出。
L-加亮或者不加亮,显示变化的行。

一些说明:
Type。此列显示 Nonp 或 Paged,分别表示非分页或分页内存使用方式。非分页内存使用方式更有可能导致问题。
Diff。此列显示该组件已执行的尚未得到释放的内存分配次数。
      Diff 列中的值是 Allocs 和 Frees 列中相应的值之差。
      如果一个组件在 Diff 列中的值随着时间而增长,则可能表明此组件存在内存泄漏。
Bytes。此值指示当前分配的内存量。如果一个组件在 Bytes 列中的值随着时间而增长,则可能表明此组件存在内存泄漏。
Mapped_Driver。此列仅在使用 g 参数时出现。它显示对标记的易于理解的描述,而且往往指示驱动程序的源文件。

Pooltag.exe的Mapped_Driver列可以显示驱动所在的目录。但信息很少,没有poolmon显示的信息多。
     操作办法是pooltags->parse all drivers in driver directory
界面的显示设置我就不说了:

使用办法:
例如:poolmon -g "C:\Program Files\Debugging Tools for Windows\triage\pooltag.txt"
每隔10-30分钟观看,d或者b命令的行列的变化,如果不停的变化(增加),就是泄露。
按d 显示的是没有释放的,按b显示的是申请的。

关于内核内存池的tag,
我以前收集的有3中办法,现在只记得一种了,
就是使用带有申请标记内存的函数。申请内存的时候一定要加标记。标记在c/c++中要用单引号,不超过4个字节。
如:ExAllocatePoolWithTag、ExallocatePoolWithTagPriority 和ExAllocatePoolWithQuotaTag,ExInitializeNPagedLookasideList 等。

如何找到池标记所使用的驱动程序,这时候大多是分析别人的驱动。
findstr /m /l “xxxx” c:\*.sys
有的时候会一个都搜索不出,这时我也不知所措,好像也应该没有这种情况。也许是你搜索的已经在,或者是已知的。
有的时候会搜索出多个,再根据每个驱动的版本和公司等做筛选。直到确定有问题的那一个。

参考资料:

如何使用内存池监视器 (Poolmon.exe) 来排查内核模式内存泄漏
http://support.microsoft.com/kb/177415/zh-cn

如何找到池标记所使用的第三方驱动程序 
http://support.microsoft.com/?kbid=298102

谁在使用池?
http://msdn.microsoft.com/zh-cn/library/windows/hardware/gg463213.aspx

PoolMon Run-time Commands
http://msdn.microsoft.com/en-us/library/ff550476.aspx

PoolMon Startup Command
http://msdn.microsoft.com/en-us/library/ff550482.aspx

PoolMon Examples
http://www.osronline.com/ddkx/ddtools/poolmon_37n7.htm
http://msdn.microsoft.com/en-us/library/ff550458.aspx

360的驱动(qutmdrv.sys)分页内存泄露案例
http://www.cnblogs.com/ahuo/archive/2010/09/29/1838439.html

瑞星的驱动(basetdi.sys)的非分页内存泄露案例
http://space.itpub.net/4670/viewspace-351828

等等。 

0 0