由于getaddrinfo()

时间:2017-01-24 13:37:36

标签: c sockets tcp memory-leaks valgrind

我将TCP流套接字连接到给定的主机名和端口。要获取主机的IP地址,我使用getaddrinfo(),如下所示

struct addrinfo hints;
struct addrinfo *result, *server;

memset(&hints, 0, sizeof(struct addrinfo)); // fill server with 0

hints.ai_family = AF_INET;   // set address family
hints.ai_protocol=0;    // set protocol type to auto
hints.ai_socktype = SOCK_STREAM;    // set type of socket to stream socket

if(getaddrinfo(HOSTNAME,PORT,&hints,&result)){
    perror("Could not resolve IP from given hostname and port (getaddrinfo)");
    freeaddrinfo(result);
    return -1;
}

if(print) printf("Connecting socket ... \n");
int connectFlag=1;
for(server=result;server!=NULL;server=server->ai_next){
    if(connect(sockfd,server->ai_addr,server->ai_addrlen)==-1){
        continue;
    }
    if(print){
        printf("Socket successfully connected\n");
    }
    break;
}

if(!connectFlag){
    printf("Could not connect to server %s.\n",HOSTNAME);
    close(sockfd);
    freeaddrinfo(result);
    return -1;
}

freeaddrinfo(result);

所有这些都发生在一个能够显示参数

的函数中
int sockfd = socket(AF_INET,SOCK_STREAM,0);

来自另一个功能。一切正常,套接字连接,我按预期接收和发送消息。

问题是,当我用

检查我创建的二进制文件时
valgrind --leak-check=full --trace-children=yes ./binary

我得到3313个字节仍然可以访问。手动解析主机并使用IP直接连接时,我没有泄漏。我用较旧的gethostbyname()替换了getaddrinfo()并获得了相同数量的仍然可达的字节。

如何摆脱这些泄漏?

Valgrind输出

   % valgrind --leak-check=full --show-leak-kinds=all ./play
==16353== Memcheck, a memory error detector
==16353== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==16353== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==16353== Command: ./a.out
==16353== 
==16353== 
==16353== HEAP SUMMARY:
==16353==     in use at exit: 3,313 bytes in 10 blocks
==16353==   total heap usage: 96 allocs, 86 frees, 54,234 bytes allocated
==16353== 
==16353== 64 bytes in 2 blocks are still reachable in loss record 1 of 5
==16353==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16353==    by 0x4016790: _dl_close_worker.part.0 (dl-close.c:393)
==16353==    by 0x4017029: _dl_close_worker (dl-close.c:125)
==16353==    by 0x4017029: _dl_close (dl-close.c:822)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353==    by 0x4F7CBAE: dlerror_run (dl-libc.c:46)
==16353==    by 0x4F7CBAE: __libc_dlclose (dl-libc.c:222)
==16353==    by 0x4FADB66: free_mem (in /lib/x86_64-linux-gnu/libc-2.23.so)
==16353==    by 0x4FAD78F: __libc_freeres (in /lib/x86_64-linux-gnu/libc-2.23.so)
==16353==    by 0x4A2868C: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-amd64-linux.so)
==16353==    by 0x4E73FAA: __run_exit_handlers (exit.c:97)
==16353==    by 0x4E74044: exit (exit.c:104)
==16353==    by 0x404162: cleanUp (in /home/a)
==16353==    by 0x401CB7: dispatch (in /home/a)
==16353== 
==16353== 71 bytes in 2 blocks are still reachable in loss record 2 of 5
==16353==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16353==    by 0x401CD89: strdup (strdup.c:42)
==16353==    by 0x401860E: _dl_load_cache_lookup (dl-cache.c:311)
==16353==    by 0x4008F98: _dl_map_object (dl-load.c:2342)
==16353==    by 0x400D9D1: openaux (dl-deps.c:63)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353==    by 0x400E011: _dl_map_object_deps (dl-deps.c:254)
==16353==    by 0x4015411: dl_open_worker (dl-open.c:280)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353==    by 0x4014BD8: _dl_open (dl-open.c:660)
==16353==    by 0x4F7C9BC: do_dlopen (dl-libc.c:87)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353== 
==16353== 71 bytes in 2 blocks are still reachable in loss record 3 of 5
==16353==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16353==    by 0x400BD23: _dl_new_object (dl-object.c:165)
==16353==    by 0x400633C: _dl_map_object_from_fd (dl-load.c:1006)
==16353==    by 0x4008A56: _dl_map_object (dl-load.c:2476)
==16353==    by 0x400D9D1: openaux (dl-deps.c:63)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353==    by 0x400E011: _dl_map_object_deps (dl-deps.c:254)
==16353==    by 0x4015411: dl_open_worker (dl-open.c:280)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353==    by 0x4014BD8: _dl_open (dl-open.c:660)
==16353==    by 0x4F7C9BC: do_dlopen (dl-libc.c:87)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353== 
==16353== 744 bytes in 2 blocks are still reachable in loss record 4 of 5
==16353==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16353==    by 0x4011EED: _dl_check_map_versions (dl-version.c:293)
==16353==    by 0x4015948: dl_open_worker (dl-open.c:286)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353==    by 0x4014BD8: _dl_open (dl-open.c:660)
==16353==    by 0x4F7C9BC: do_dlopen (dl-libc.c:87)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353==    by 0x4F7CA73: dlerror_run (dl-libc.c:46)
==16353==    by 0x4F7CA73: __libc_dlopen_mode (dl-libc.c:163)
==16353==    by 0x4F623BD: nss_load_library (nsswitch.c:358)
==16353==    by 0x4F630F3: __nss_lookup_function (nsswitch.c:466)
==16353==    by 0x4F630F3: __nss_next2 (nsswitch.c:242)
==16353==    by 0x4F535FA: gethostbyname2_r@@GLIBC_2.2.5 (getXXbyYY_r.c:281)
==16353==    by 0x4F259DE: gaih_inet (getaddrinfo.c:622)
==16353== 
==16353== 2,363 bytes in 2 blocks are still reachable in loss record 5 of 5
==16353==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16353==    by 0x400BA25: _dl_new_object (dl-object.c:75)
==16353==    by 0x400633C: _dl_map_object_from_fd (dl-load.c:1006)
==16353==    by 0x4008A56: _dl_map_object (dl-load.c:2476)
==16353==    by 0x400D9D1: openaux (dl-deps.c:63)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353==    by 0x400E011: _dl_map_object_deps (dl-deps.c:254)
==16353==    by 0x4015411: dl_open_worker (dl-open.c:280)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353==    by 0x4014BD8: _dl_open (dl-open.c:660)
==16353==    by 0x4F7C9BC: do_dlopen (dl-libc.c:87)
==16353==    by 0x4010393: _dl_catch_error (dl-error.c:187)
==16353== 
==16353== LEAK SUMMARY:
==16353==    definitely lost: 0 bytes in 0 blocks
==16353==    indirectly lost: 0 bytes in 0 blocks
==16353==      possibly lost: 0 bytes in 0 blocks
==16353==    still reachable: 3,313 bytes in 10 blocks
==16353==         suppressed: 0 bytes in 0 blocks
==16353== 
==16353== For counts of detected and suppressed errors, rerun with: -v
==16353== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

如果我添加valgrind选项--trace-children = yes,则valgrind会检查子进程。我没有输出这个,因为泄漏正在这个父进程中发生。

编辑

事实证明我们无法在其他硬件上重现valgrind输出。在这个服务器上,getaddrinfo()生成了这个valgrind输出以及gethostbyname()。我们没有进一步观察到这种行为可能来自何处。

1 个答案:

答案 0 :(得分:0)

“仍然可以访问”意味着程序已经分配了内存,并且在终止时它仍然具有对它的引用。这可能意味着第一次调用时getaddrinfo()和gethostbyname()会分配重用的内存。

此SO答案也可能适用:https://stackoverflow.com/a/13230399/2696475