在启用了泄漏检查时,程序退出时会自动生成泄漏报告。所有可能的泄漏都会报告出来,但前提是程序不是使用 kill 命令中止的。报告中的详细程度由 dbx 环境变量 rtc_mel_at_exit 控制(请参见设置 dbx 环境变量)。缺省情况下,会生成简短的泄漏报告。
报告按泄漏的合并大小排序。先报告真正的内存泄漏,然后报告可能的泄漏。详细报告包含详细的栈跟踪信息,其中包括行号和可用的源文件。
两种报告都包括内存泄漏错误的下列信息:
信息 |
说明 |
---|---|
大小 |
泄漏块的大小。 |
位置 |
泄漏块被分配到的位置。 |
地址 |
泄漏块的地址。 |
栈 |
分配时调用栈,由 check -frames |
以下是相应的简短内存泄漏报告。
Actual leaks report (actual leaks: 3 total size: 2427 bytes) Total Num of Leaked Allocation call stack Size Blocks Block Address ========== ====== ========== ======================================= 1852 2 - true_leak < true_leak 575 1 0x22150 true_leak < main Possible leaks report (possible leaks: 1 total size: 8 bytes) Total Num of Leaked Allocation call stack Size Blocks Block Address ========== ====== ========== ======================================= 8 1 0x219b0 in_block < main |
以下是一个典型的详细泄漏报告。
Actual leaks report (actual leaks: 3 total size: 2427 bytes) Memory Leak (mel): Found 2 leaked blocks with total size 1852 bytes At time of each allocation, the call stack was: [1] true_leak() at line 220 in "leaks.c" [2] true_leak() at line 224 in "leaks.c" Memory Leak (mel): Found leaked block of size 575 bytes at address 0x22150 At time of allocation, the call stack was: [1] true_leak() at line 220 in "leaks.c" [2] main() at line 87 in "leaks.c" Possible leaks report (possible leaks: 1 total size: 8 bytes) Possible memory leak -- address in block (aib): Found leaked block of size 8 bytes at address 0x219b0 At time of allocation, the call stack was: [1] in_block() at line 177 in "leaks.c" [2] main() at line 100 in "leaks.c" |
可以随时通过使用 showleaks 命令获取泄漏报告,其中会报告自上次执行 showleaks 命令以来的新内存泄漏。有关更多信息,请参见showleaks 命令。
由于单个泄漏的数量可能会非常大,因此运行时检查会自动将同一位置分配的泄漏合并到一个合并泄漏报告中。是合并泄漏还是分别报告泄漏由 number-of-frames-to-match 参数控制,该参数通过 check -leaks 中的 -match m 选项或 showleaks 命令的 -m 选项指定。如果两个或更多泄漏分配时的调用栈与 m 帧在严格程序计数器等级匹配,便会在一个合并泄漏报告中报告这些泄漏。
假设有下列三个调用序列:
块 1 |
块 2 |
块 3 |
---|---|---|
[1] malloc |
[1] malloc |
[1] malloc |
[2] d() at 0x20000 |
[2] d() at 0x20000 |
[2] d() at 0x20000 |
[3] c() at 0x30000 |
[3] c() at 0x30000 |
[3] c() at 0x31000 |
[4] b() at 0x40000 |
[4] b() at 0x41000 |
[4] b() at 0x40000 |
[5] a() at 0x50000 |
[5] a() at 0x50000 |
[5] a() at 0x50000 |
如果所有这些块均导致内存泄漏,则 m 值决定泄漏按单独泄漏还是一个重复泄漏来报告。如果 m 为 2,则块 1 和块 2 按一个重复泄漏来报告,因为两个调用序列 malloc() 上的 2 个栈帧相同。块 3 将按单独泄漏来报告,因为 c() 的跟踪与其他块不匹配。如果 m 大于 2,运行时检查会将所有泄漏按单独泄漏来报告。(malloc 不显示在泄漏报告中。)
一般情况下,m 值越小,生成的单个泄漏报告越少,合并泄漏报告越多。m 值越大,生成的合并泄漏报告越少,单个泄漏报告越多。