2017-01-24 9 views
0

Я подключаю сокет TCP-потока к данному имени хоста и порту. Чтобы получить IP-адрес хоста я использую getaddrinfo() следующимУтечка памяти Valgrind из-за 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); 

Все это происходит внутри функции, reveivecs параметр

int sockfd = socket(AF_INET,SOCK_STREAM,0); 

из другой функции. Все работает нормально, сокет подключается, и я получаю и отправляю сообщения, как ожидалось.

Проблема заключается в том, когда я просматриваю созданный бинарный файл с

valgrind --leak-check=full --trace-children=yes ./binary 

Я получаю 3313 байт еще достижима. Когда вы разрешаете хост вручную и напрямую подключаетесь, используя IP, я не получаю утечек. Я заменил getaddrinfo() на старшего gethostbyname() и получил то же количество доступных до сих пор байтов.

Как я могу избавиться от этих утечек?

выход 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: [email protected]@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-дети = да Valgrind проверяет дочерний процесс. Я не выводил это, потому что в этом родительском процессе происходит утечка .

EDIT

Оказалось, что мы не смогли воспроизвести вывод VALGRIND на другом оборудовании. На этом сервере getaddrinfo() создал этот вывод valgrind, а также gethostbyname(). Мы еще не заметили, откуда такое поведение.

+0

«Тем не менее достижимым» не означает, что утечка памяти. –

+0

Я читал это раньше. Не могли бы вы объяснить, что «все еще достижимо» означает, что это не утечка? Это звучит очень похоже на то, что указатели являются «доступными», поэтому не удаляются до конца программы. – datell

+0

Честно говоря, я не могу ответить на это, как я не знаю. Насколько я помню, утечки маркера «Определенно потеряны» и «Возможно потеряны». И «Определенно потерянный» - это главное, вы должны исследовать и исправлять. –

ответ

0

«Все еще достижимый» означает, что программа выделила память, и по-прежнему имеет ссылку на нее во время завершения. Вероятно, это означает, что getaddrinfo() и gethostbyname() при первом вызове выделяют память, которая используется повторно.

Этот SO-ответ может быть также применимо: https://stackoverflow.com/a/13230399/2696475