2016-12-25 19 views
1

私はgetaddrinfo()freeaddrinfo()を呼び出す簡単なプログラムを持っています。 私はvalgrindを実行して、メモリリークがないことを示します。`getaddrinfo()`のメモリ割り当て

in use at exit: 0 bytes in 0 blocks 
total heap usage: 108 allocs, 109 frees 

しかし、私は、メモリリークを検出するために、malloc()free()でターゲット・プロセスおよびトラップを添付しmemleaxという名前のメモリデバッガを書きました。私はmemleaxを使ってgetaddrinfo()プログラムを検出し、free()を43回しか捕まえません。

それから私は 、malloc-hooksによってmalloc()free()をフックし、それはまた、free()のみ43回を示しています。

私の質問は、valgrindとhooking-mallocの違いは何ですか?

オリジナルコード:

#include <sys/types.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <stdio.h> 

int main() 
{ 
    struct addrinfo *aihead; 

    sleep(4); 
    printf(" --- getaddrinfo ---\n"); 
    int error = getaddrinfo("dig.chouti.com", "http", NULL, &aihead); 
    if(error) { 
    printf("error: %s\n", gai_strerror(error)); 
    return error; 
    } 
    sleep(4); 
    printf("\n\n\n --- freeaddrinfo ---\n"); 
    freeaddrinfo(aihead); 
    sleep(4); 
    return 0; 
} 

コードのmalloc-フック

#include <sys/types.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <stdio.h> 

/* Prototypes for __malloc_hook, __free_hook */ 
#include <malloc.h> 

/* Prototypes for our hooks. */ 
static void my_init_hook (void); 
static void *my_malloc_hook (size_t, const void *); 
static void my_free_hook (void*, const void *); 

static void *(*old_malloc_hook) (size_t, const void *); 
static void (*old_free_hook) (void*, const void *); 

static void 
my_init (void) 
{ 
    old_malloc_hook = __malloc_hook; 
    old_free_hook = __free_hook; 
    __malloc_hook = my_malloc_hook; 
    __free_hook = my_free_hook; 
} 

static void * 
my_malloc_hook (size_t size, const void *caller) 
{ 
    void *result; 
    /* Restore all old hooks */ 
    __malloc_hook = old_malloc_hook; 
    __free_hook = old_free_hook; 
    /* Call recursively */ 
    result = malloc (size); 
    /* Save underlying hooks */ 
    old_malloc_hook = __malloc_hook; 
    old_free_hook = __free_hook; 
    /* printf might call malloc, so protect it too. */ 
    printf ("malloc (%u) returns %p\n", (unsigned int) size, result); 
    /* Restore our own hooks */ 
    __malloc_hook = my_malloc_hook; 
    __free_hook = my_free_hook; 
    return result; 
} 

static void 
my_free_hook (void *ptr, const void *caller) 
{ 
    /* Restore all old hooks */ 
    __malloc_hook = old_malloc_hook; 
    __free_hook = old_free_hook; 
    /* Call recursively */ 
    free (ptr); 
    /* Save underlying hooks */ 
    old_malloc_hook = __malloc_hook; 
    old_free_hook = __free_hook; 
    /* printf might call free, so protect it too. */ 
    printf ("freed pointer %p\n", ptr); 
    /* Restore our own hooks */ 
    __malloc_hook = my_malloc_hook; 
    __free_hook = my_free_hook; 
} 

int main() 
{ 
    my_init(); 

    struct addrinfo *aihead; 

    printf(" --- getaddrinfo ---\n"); 
    int error = getaddrinfo("dig.chouti.com", "http", NULL, &aihead); 
    if(error) { 
    printf("error: %s\n", gai_strerror(error)); 
    return error; 
    } 
    sleep(4); 
    printf("\n\n\n --- freeaddrinfo ---\n"); 
    freeaddrinfo(aihead); 
    sleep(4); 
    return 0; 
} 
+0

あなたの質問は、stackoverflowでもっと話題になるでしょう –

答えて

1

と私はvalgrindのの出力でこれを見つける:

--13197-- Discarding syms at 0x55f9240-0x5600454 in /usr/lib64/libnss_files-2.17.so due to mu 
--13197-- Discarding syms at 0x580b100-0x580e590 in /usr/lib64/libnss_dns-2.17.so due to munm 
--13197-- Discarding syms at 0x5a13a40-0x5a22854 in /usr/lib64/libresolv-2.17.so due to munma 
==13197== Invalid free()/delete/delete[]/realloc() 
==13197== at 0x4C2AD17: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
==13197== by 0x4F9963B: __libc_freeres (in /usr/lib64/libc-2.17.so) 
==13197== by 0x4A246B4: _vgnU_freeres (in /usr/lib64/valgrind/vgpreload_core-amd64-linux.s 
==13197== by 0x4E6DE2A: __run_exit_handlers (in /usr/lib64/libc-2.17.so) 
==13197== by 0x4E6DEB4: exit (in /usr/lib64/libc-2.17.so) 
==13197== by 0x4E56B1B: (below main) (in /usr/lib64/libc-2.17.so) 
==13197== Address 0x51f03d0 is 0 bytes inside data symbol "noai6ai_cached" 

それにlibc-NSSがでいくつかのメモリを解放しているようですexit()の後の__run_exit_handlers()

したがって、valgridは、ターゲットプロセスのexit()の後にメモリをトレースする可能性があります。 mallocフックはexit()の後で動作しなくなります。