Memory `getaddrinfo()的内存分配`

Memory `getaddrinfo()的内存分配`,memory,memory-leaks,Memory,Memory Leaks,我有一个简单的程序,它调用getaddrinfo()和freeaddrinfo()。 我在上面运行了valgrind,它显示没有内存泄漏 in use at exit: 0 bytes in 0 blocks total heap usage: 108 allocs, 109 frees 但是,我编写了一个名为的内存调试器,它将目标进程和陷阱附加到malloc()和free()以检测内存泄漏。我使用memleax检测getaddrinfo()程序,它只捕获free()43次 然后我用钩子钩住m

我有一个简单的程序,它调用
getaddrinfo()
freeaddrinfo()
。 我在上面运行了valgrind,它显示没有内存泄漏

in use at exit: 0 bytes in 0 blocks
total heap usage: 108 allocs, 109 frees
但是,我编写了一个名为的内存调试器,它将目标进程和陷阱附加到
malloc()
free()
以检测内存泄漏。我使用memleax检测
getaddrinfo()
程序,它只捕获
free()
43次

然后我用钩子钩住
malloc()
free()
, 而且它也只显示了43次
free()

所以我的问题是,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;
}
#包括
#包括
#包括
#包括
#包括
int main()
{
结构addrinfo*aihead;
睡眠(4);
printf(“--getaddrinfo--\n”);
int error=getaddrinfo(“dig.chouti.com”、“http”、NULL和aihead);
如果(错误){
printf(“错误:%s\n”,gai_strerror(错误));
返回误差;
}
睡眠(4);
printf(“\n\n\n--freeaddrinfo--\n”);
freeaddrinfo(aihead);
睡眠(4);
返回0;
}
mallochook代码

#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;
}
#包括
#包括
#包括
#包括
#包括
/*malloc钩子和free钩子的原型*/
#包括
/*我们的钩子原型*/
静态void my_init_hook(void);
静态空隙*my_malloc_挂钩(尺寸,常数空隙*);
静态void my_free_hook(void*,const void*);
静态空隙*(*旧马洛克钩)(尺寸,常数空隙*);
静态无效(*旧的自由钩)(无效*,常数无效*);
静态空隙
my_init(无效)
{
old_malloc_hook=_malloc_hook;
old_free_hook=_free_hook;
__malloc_hook=我的malloc_hook;
__自由钩=我的自由钩;
}
静态空隙*
my_malloc_hook(大小,常量无效*调用者)
{
无效*结果;
/*恢复所有旧挂钩*/
__malloc_hook=旧的malloc_hook;
__自由钩=旧的自由钩;
/*递归调用*/
结果=malloc(大小);
/*保存底层钩子*/
old_malloc_hook=_malloc_hook;
old_free_hook=_free_hook;
/*printf可能会调用malloc,所以也要保护它*/
printf(“malloc(%u)返回%p\n”,(无符号整数)大小,结果);
/*自食其力*/
__malloc_hook=我的malloc_hook;
__自由钩=我的自由钩;
返回结果;
}
静态空隙
my_free_hook(void*ptr,const void*caller)
{
/*恢复所有旧挂钩*/
__malloc_hook=旧的malloc_hook;
__自由钩=旧的自由钩;
/*递归调用*/
免费(ptr);
/*保存底层钩子*/
old_malloc_hook=_malloc_hook;
old_free_hook=_free_hook;
/*printf可能是免费的,所以也要保护它*/
printf(“释放的指针%p\n”,ptr);
/*自食其力*/
__malloc_hook=我的malloc_hook;
__自由钩=我的自由钩;
}
int main()
{
我的_init();
结构addrinfo*aihead;
printf(“--getaddrinfo--\n”);
int error=getaddrinfo(“dig.chouti.com”、“http”、NULL和aihead);
如果(错误){
printf(“错误:%s\n”,gai_strerror(错误));
返回误差;
}
睡眠(4);
printf(“\n\n\n--freeaddrinfo--\n”);
freeaddrinfo(aihead);
睡眠(4);
返回0;
}

我在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()之后的uu run_exit_handlers()释放了一些内存


因此,valgrid可能会在目标进程退出()后继续跟踪内存。而malloc hook在exit()之后停止工作。

您的问题将更多地集中在stackoverflow的主题上