在介绍之前,先介绍一下libmum,libmum是一个对内存进行检测的库,如果想使用mdb检查内存泄露,在程序运行时需要加载libmum库。
export UMEM_DEBUG=default
export UMEM_LOGGING=transaction
export LD_PRELOAD=libumem.so.1
下面这个程序有明星的内存泄露。申请的内存没有被释放掉。
使用ps -ef 找到运行程序的pid,使用gcore生成一个core文件,利用mdb打开core文件
bash-3.2# mdb core.237
Loading modules: [ libumem.so.1 ld.so.1 ]
> ::findleaks
CACHE LEAKED BUFCTL CALLER
0806a290 1 0807f200 libstdc++.so.6.0.3`_Znwj+0x29
0806a290 60 0807f2f0 libstdc++.so.6.0.3`_Znwj+0x29
------------------------------------------------------------------------
Total 61 buffers, 976 bytes
>
可以看到libstdc++.so.6.0.3`_Znwj+0x29有60个leaked,根据bufctl的地址查看bufctl的信息。
> 0807f2f0::bufctl -v
ADDR BUFADDR TIMESTAMP THREAD
CACHE LASTLOG CONTENTS
807f2f0 8079fa0 ad78129dfba5 1
806a290 0 0
libumem.so.1`umem_cache_alloc_debug+0x144
libumem.so.1`umem_cache_alloc+0x153
libumem.so.1`umem_alloc+0xcd
libumem.so.1`malloc+0x2a
libstdc++.so.6.0.3`_Znwj+0x29
main+0x27
_start+0x80
内存泄露的程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <iostream.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> class TestClass { public: TestClass() { cout << "no-argument" <<endl; } TestClass(const char *name) { cout << "arg = " << name << endl; } }; int main(int argc, char **argv) { TestClass *t; TestClass *tt; while (1) { t = new TestClass(); t = new TestClass("Hello."); tt = new TestClass("Goodbye."); delete(t); delete(tt); sleep(1); } } |