LeakDiag的使用和形成的LOG文件的分析方法

来源:互联网 发布:用友nc java插件 编辑:程序博客网 时间:2024/06/10 01:52
一,使用

    LeakDiag版本1.25的下载地址为:

http://iterzebra.download.csdn.net/

    微软官方地址:

     ftp://ftp.microsoft.com/PSS/Tools/Developer%20Support%20Tools/LeakDiag/
     ftp://ftp.microsoft.com/PSS/Tools/Developer%20Support%20Tools/LDGrapher/
   (官方地址有时无法访问)

    解压后,有LDGrapher_setup和leakdiag125两个安装程序,进行安装即可。
    默认情况下,leakdiag被安装在C:\leakdiag下;LDGrapher 被安装在C:\leakdiag\LDGrapher下。C:\leakdiag\Logs是其产生的XML形式的log文件所在目录。C: \leakdiag\autodiag是其.ini形式配置文件。如果需要定时的采集log,需要在该配置文件中进行配置。


    LeakDiag可以用以检测无论是简单exe程序还是Windows Service的内存泄漏问题。不需要停止程序,就可以进行对程序的内存监测。

    LeakDiag形成的LOG文件中,包含了分配了内存,但是在进行LOG输出(快照)的时候没有进行释放的调用栈情况。LeakDiag在start后对进程进行实时的进行监测,在输出LOG的时候,进行结果形成,可以设置定时的输出。

    使用LeakDiag为了保证正确的解析调用栈,需要设置对程序使用的符号信息进行搜索的路径。包括public symbol path和本地程序的符号信息,public symbol path可以设置成:
srv*c:\symcache* http://msdl.microsoft.com/download/symbols
其是微软提供的底层DLL、API的符号信息。系统修补程序打包在修补包中,有些则有独立的下载。服务包的使用的符号信息,可以在微软网站上下载,或者在Service Pack CD中。将本地程序的符号信息(即PDB(Program Debug Database,程序调试数据库)文件的目录),也请添加到符号搜索路径中。

    对于大规模程序,勾选Resolve symbols when logging,不是很好的选择。可以在LOG完成后,再进行符号解析。因为如果勾选,在形成LOG的时候,对于大型软件需要进行大量的符号解析。

    对于Memory Allocators选项的意义分别是:

        Virtual Allocator (VirtualAlloc?)
        Windows Heap Allocator (HeapAlloc?)[DEFAULT]
        COM Allocator (CoTask?)
        C Runtime Allocator (msvcrt new)
        TLS Slot Allocator (TlsAlloc?)

可以进行多个监测。

二,分析

    LeakDiag形成的XML形式的LOG文件的分析方法,大致有三个。

1,人工读取、分析XML文档

    XML文档的开始部分是模式定义(XML规范规定的)。LeakDiag产生的往往以“<xs:schema id="logdata"”开始,以 “</xs:schema>”结尾。
    中间部分以“LEAKS”作为标识。其对于分配了内存,但是没有检测到相应释放的函数调用栈进行了记录。
    每一个记录都以STACK为标识。记录包括了STACK的大概情况、STACKSTATS(STACK状态)、调用栈帧以及该栈的ID号四个部分。每一个可能有内存泄漏问题的栈,对应在这样的一条记录中。一条记录的例子如下:

<STACK numallocs="036290" size="049" totalsize="01801690">
<STACKSTATS>
<SIZESTAT size="05380" numallocs="01"/>
<SIZESTAT size="028" numallocs="0111"/>
<SIZESTAT size="052" numallocs="01"/>
<SIZESTAT size="032" numallocs="07007"/>
<SIZESTAT size="060" numallocs="0161"/>
<SIZESTAT size="08" numallocs="0192"/>
<SIZESTAT size="018" numallocs="0113"/>
<SIZESTAT size="064" numallocs="05686"/>
<SIZESTAT size="02" numallocs="04553"/>
<SIZESTAT size="048" numallocs="020"/>
<SIZESTAT size="016" numallocs="0144"/>
<SIZESTAT size="010" numallocs="094"/>
<SIZESTAT size="014" numallocs="0103"/>
<SIZESTAT size="038" numallocs="018"/>
<SIZESTAT size="040" numallocs="05401"/>
<SIZESTAT size="024" numallocs="05944"/>
<SIZESTAT size="0120" numallocs="04860"/>
<SIZESTAT size="0128" numallocs="01800"/>
<SIZESTAT size="080" numallocs="02"/>
<SIZESTAT size="04" numallocs="02"/>
<SIZESTAT size="0312" numallocs="01"/>
<SIZESTAT size="050" numallocs="020"/>
<SIZESTAT size="054" numallocs="022"/>
<SIZESTAT size="078" numallocs="01"/>
<SIZESTAT size="034" numallocs="025"/>
<SIZESTAT size="058" numallocs="08"/>
<HEAPSTAT handle="b20000" numallocs="036290"/>
</STACKSTATS>
<FRAME num="0" dll="MSVCR71.dll" function ="_crtLCMapStringA" offset="0x305" filename="" line="" addr="0x3916B3" />
<FRAME num="1" dll="MSVCR71.dll" function ="_crtLCMapStringA" offset="0x32D" filename="" line="" addr="0x3916DB" />
<STACKID>059459A8</STACKID>
</STACK>

    最后部分是概要信息,以“SUMMARY_INFO”作为标识。其包括进程名称、进程ID等系统进程信息,LeakDiag的版本等信息,虚拟内存页、物理内存页的使用情况的内存信息,模块信息等。
    中间部分对于我们的分析最有用处。


2,使用IDParser

    IDParser可以自动的读取LOG文件,并对其中的数据进行统计,以表格形式显示。但是没有找到该软件,据说是Microsoft将其合并在某个DEBUG工具中了。

3,使用LDGrapher

    对于多于两个LOG文件时,可以使用这个工具。其以多个LOG文件作为输入,对每个LOG文件中记录的可能内存泄漏的调用栈进行以图形形式的显示。
    图形中的不同颜色代表不同的函数调用栈,线上的每个点代表一次LOG文件。我们可以双击线,IDGrapher会产生一个对应这个线的统计表,其中可以看到调用栈帧,从而确定在哪个函数中进行的分配。
    为了让LDGrapher正确输出,我们必须保证,打开的多个LOG文件是对同一种Memory allocators的监视(在leakdiag工具使用时进行设置)。
    IDGrapher是以每个LOG作为采样点进行的图形绘制。

参考:
[1] http://www.codeproject.com/KB/cpp/Tools.aspx
[2] http://mcfunley.com/277/using-leakdiag-to-debug-unmanaged-memory-leaks/comment-page-1
[3]软件的联机帮助文档