我有一个简单的程序,可以调用getaddrinfo()
和freeaddrinfo()
。
我在上面运行valgrind,它表明没有内存泄漏。
in use at exit: 0 bytes in 0 blocks
total heap usage: 108 allocs, 109 frees
但是,我编写了一个名为memleax的内存调试器,它将目标进程和陷阱附加到malloc()
和free()
以检测内存泄漏。我使用memleax来检测getaddrinfo()
程序,它只捕获free()
43次。
然后我将malloc()
和free()
挂钩到malloc-hooks,
它还显示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-hook的代码
#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 :(得分: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-hook在exit()之后停止工作。