LD_PRELOAD 在 ls 上与 malloc/free 共享库

LD_PRELOAD shared library with malloc/free on ls

我试图检测程序中的内存泄漏。为了得到这个想法,我通过 LD_PRELOAD'ing 共享库在 ls 上尝试了 malloc()free()

void* malloc(size_t size)
{
    char buf[60];
    static void* (*real_malloc)(size_t) = NULL;

    if (real_malloc == NULL) {
        *(void**)(&real_malloc) = dlsym(RTLD_NEXT, "malloc");
    }

    void* mem = real_malloc(size);
    sprintf(buf, "malloc called, size = %5zu, ptr=%p\n", size, mem);
    write(2, buf, strlen(buf));
    return mem;
}

和运行:

LD_PRELOAD=./libmcount.so ls

我得到以下输出:

malloc called, size =   472, ptr=0x556d7a7682d0
malloc called, size =   120, ptr=0x556d7a7684b0
malloc called, size =  1024, ptr=0x556d7a768530
free called, ptr address = 0x556d7a7684b0
free called, ptr address = 0x556d7a768530
free called, ptr address = 0x556d7a7682d0
free called, ptr address = (nil)
malloc called, size =     5, ptr=0x556d7a768940
free called, ptr address = 0x556d7a768940
malloc called, size =   120, ptr=0x556d7a7684b0
malloc called, size =    12, ptr=0x556d7a768940
malloc called, size =   776, ptr=0x556d7a768960
malloc called, size =   112, ptr=0x556d7a768c70
malloc called, size =  1336, ptr=0x556d7a768cf0
malloc called, size =   216, ptr=0x556d7a769230
malloc called, size =   432, ptr=0x556d7a769310
malloc called, size =   104, ptr=0x556d7a7694d0
malloc called, size =    88, ptr=0x556d7a769540
malloc called, size =   120, ptr=0x556d7a7695a0
malloc called, size =   168, ptr=0x556d7a769620
malloc called, size =   104, ptr=0x556d7a7696d0
malloc called, size =    80, ptr=0x556d7a769740
malloc called, size =   192, ptr=0x556d7a7697a0
malloc called, size =    12, ptr=0x556d7a769870
malloc called, size =    12, ptr=0x556d7a769890
malloc called, size =    12, ptr=0x556d7a7698b0
malloc called, size =    12, ptr=0x556d7a7698d0
malloc called, size =    12, ptr=0x556d7a7698f0
malloc called, size =    12, ptr=0x556d7a769910
malloc called, size =     5, ptr=0x556d7a769930
free called, ptr address = 0x556d7a769930
malloc called, size =   120, ptr=0x556d7a769950
malloc called, size =    12, ptr=0x556d7a769930
malloc called, size =   776, ptr=0x556d7a7699d0
malloc called, size =   112, ptr=0x556d7a769ce0
malloc called, size =  1336, ptr=0x556d7a769d60
malloc called, size =   216, ptr=0x556d7a76a2a0
malloc called, size =   432, ptr=0x556d7a76a380
malloc called, size =   104, ptr=0x556d7a76a540
malloc called, size =    88, ptr=0x556d7a76a5b0
malloc called, size =   120, ptr=0x556d7a76a610
malloc called, size =   168, ptr=0x556d7a76a690
malloc called, size =   104, ptr=0x556d7a76a740
malloc called, size =    80, ptr=0x556d7a76a7b0
malloc called, size =   192, ptr=0x556d7a76a810
malloc called, size =    12, ptr=0x556d7a76a8e0
malloc called, size =    12, ptr=0x556d7a76a900
malloc called, size =    12, ptr=0x556d7a76a920
malloc called, size =    12, ptr=0x556d7a76a940
malloc called, size =    12, ptr=0x556d7a76a960
malloc called, size =    12, ptr=0x556d7a76a980
malloc called, size =   281, ptr=0x556d7a76a9a0
free called, ptr address = (nil)
free called, ptr address = (nil)
malloc called, size =    34, ptr=0x556d7a76aad0
malloc called, size =    10, ptr=0x556d7a76ab00
malloc called, size =    56, ptr=0x556d7a76ab20
malloc called, size =    56, ptr=0x556d7a76ab60
malloc called, size =   128, ptr=0x556d7a76aba0
malloc called, size = 20000, ptr=0x556d7a76ac30
malloc called, size =    32, ptr=0x556d7a76fa60
malloc called, size =     2, ptr=0x556d7a76fa90
malloc called, size = 32816, ptr=0x556d7a76fab0
malloc called, size =    11, ptr=0x556d7a777af0
malloc called, size =    13, ptr=0x556d7a777b10
malloc called, size =    15, ptr=0x556d7a777b30
malloc called, size =    14, ptr=0x556d7a777b50
malloc called, size =    18, ptr=0x556d7a777b70
malloc called, size =     7, ptr=0x556d7a777b90
malloc called, size =     5, ptr=0x556d7a777bb0
malloc called, size =    12, ptr=0x556d7a777bd0
free called, ptr address = 0x556d7a76fab0
free called, ptr address = (nil)
malloc called, size =   192, ptr=0x556d7a76fab0
malloc called, size =  1088, ptr=0x556d7a76fd10
malloc called, size =  1024, ptr=0x556d7a768530
1-build.sh  libmcount.so
2-run.sh  malloc.c
free called, ptr address = 0x556d7a76fa90
free called, ptr address = (nil)
free called, ptr address = 0x556d7a76fa60
free called, ptr address = 0x556d7a768530

令我困惑的是,尽管我省略了 realloc/calloc/memalign 函数,但输出中的 malloc 调用比自由调用多得多。我认为他们应该配对。 Valgrind 报告没有泄漏。

默认情况下,Valgrind 不会显示“可访问”内存块,即程序仍可通过全局指针或堆栈变量访问的块。这可以用 --show-reachable=yes.

改变

至于未释放的内存,通常终止程序比费心释放所有分配的块更快。