C/C++内存泄漏检测 —— memleax

时间:2023-01-11 21:24:38

memleax是个开源项目,原理是通过注入hook目标进程的malloc(new也是用的malloc)内存分配函数,在指定时间未释放则认为内存泄漏。优点是不需要重启,attach到目标进程。

github地址:http://wubingzheng.github.io/memleax/

ubuntu编译需要安装 libunwind8-dev、libelf-dev 和 libdw-dev 3个库。

测试代码:

#include <iostream>
#include <unistd.h>
#include <fstream>

using namespace std;

int main()
{
    while (1)
    {
        cout << "Hello world" << endl;
        cout << "Hello world" << endl;
        cout << "Hello world" << endl;
        cout << "Hello world" << endl;
        cout << "Hello world" << endl;


        ofstream myfile;
        myfile.open ("1.txt");

        cout << "Hello world" << endl;
        cout << "Hello world" << endl;
        cout << "Hello world" << endl;
        cout << "Hello world" << endl;
        cout << "Hello world" << endl;
        cout << "Hello world" << endl;
        cout << "Hello world" << endl;
        char *p = new char(100);

        usleep(3000 * 1000);
    }
}

 

$ sudo memleax -e 2 2972

== Begin monitoring process 2972...
CallStack[1]: memory expires with 552 bytes, backtrace:
    0x00007f07e2a8e4a0  libc-2.21.so  __libc_malloc()+0  /build/buildd/glibc-2.21/libio/genops.c:1320
    0x00007f07e2a7911d  libc-2.21.so  ?()  /build/buildd/glibc-2.21/libio/iofopen.c:69
    0x00007f07e3067120  libstdc++.so  _ZNSt12__basic_fileIcE4openEPKcSt13_Ios_Openmo()+48
    0x00007f07e30a918a  libstdc++.so  _ZNSt13basic_filebufIcSt11char_traitsIcEE4open()+74
    0x00007f07e30a93e0  libstdc++.so  _ZNSt14basic_ofstreamIcSt11char_traitsIcEE4ope()+16
    0x0000000000400c31  cppleak  main()+219  /home/kiiim/aosp/memleak_test/1.cpp:19
CallStack[2]: memory expires with 8192 bytes, backtrace:
    0x00007f07e2a8e4a0  libc-2.21.so  __libc_malloc()+0  /build/buildd/glibc-2.21/libio/genops.c:1320
    0x00007f07e3049698  libstdc++.so  _Znwm()+24
    0x00007f07e3049749  libstdc++.so  _Znam()+9
    0x00007f07e30a9231  libstdc++.so  _ZNSt13basic_filebufIcSt11char_traitsIcEE4open()+241
    0x00007f07e30a93e0  libstdc++.so  _ZNSt14basic_ofstreamIcSt11char_traitsIcEE4ope()+16
    0x0000000000400c31  cppleak  main()+219  /home/kiiim/aosp/memleak_test/1.cpp:19
CallStack[3]: memory expires with 1 bytes, backtrace:
    0x00007f07e2a8e4a0  libc-2.21.so  __libc_malloc()+0  /build/buildd/glibc-2.21/libio/genops.c:1320
    0x00007f07e3049698  libstdc++.so  _Znwm()+24
    0x0000000000400cff  cppleak  main()+425  /home/kiiim/aosp/memleak_test/1.cpp:28
CallStack[2]: expired-memory frees after 3 seconds
CallStack[1]: expired-memory frees after 3 seconds
CallStack[1]: memory expires with 552 bytes, 2 times again
CallStack[2]: memory expires with 8192 bytes, 2 times again
CallStack[3]: memory expires with 1 bytes, 2 times again
CallStack[2]: expired-memory frees after 3 seconds
CallStack[1]: expired-memory frees after 3 seconds
CallStack[1]: memory expires with 552 bytes, 3 times again
CallStack[2]: memory expires with 8192 bytes, 3 times again
CallStack[3]: memory expires with 1 bytes, 3 times again
CallStack[2]: expired-memory frees after 3 seconds
Warning: too many expired-free at CallStack[2]. will not show this CallStack later
CallStack[1]: expired-memory frees after 3 seconds
Warning: too many expired-free at CallStack[1]. will not show this CallStack later
CallStack[3]: memory expires with 1 bytes, 4 times again
CallStack[3]: memory expires with 1 bytes, 5 times again
CallStack[3]: memory expires with 1 bytes, 6 times again
CallStack[3]: memory expires with 1 bytes, 7 times again
CallStack[3]: memory expires with 1 bytes, 8 times again
CallStack[3]: memory expires with 1 bytes, 9 times again
CallStack[3]: memory expires with 1 bytes, backtrace:
0x00007f07e2a8e4a0 libc-2.21.so __libc_malloc()+0 /build/buildd/glibc-2.21/libio/genops.c:1320
0x00007f07e3049698 libstdc++.so _Znwm()+24
0x0000000000400cff cppleak main()+425 /home/kiiim/aosp/memleak_test/1.cpp:28

 

标志 char *p = new char(100); 的内存泄漏。

CallStack[2]: memory expires with 8192 bytes, 3 times again

CallStack[2]:expired-memory frees after 3 seconds Warning: too many expired-free at CallStack[2]. will not show this CallStack later

文件句柄因为在while结束时会释放,程序很人性化。屏蔽了这个告警。