title: Valgrind memory leaks because of getaddrinfo()
body: <p>I connect a TCP stream socket to a given hostname and port. To get the host's IP address I use <a href="http://man7.org/linux/man-pages/man3/getaddrinfo.3.html" rel="nofollow noreferrer">getaddrinfo()</a> as follows</p>
  <pre><code>struct addrinfo hints;
  struct addrinfo *result, *server;
  
  memset(&amp;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,&amp;hints,&amp;result)){
      perror(&quot;Could not resolve IP from given hostname and port (getaddrinfo)&quot;);
      freeaddrinfo(result);
      return -1;
  }
  
  if(print) printf(&quot;Connecting socket ... \n&quot;);
  int connectFlag=1;
  for(server=result;server!=NULL;server=server-&gt;ai_next){
      if(connect(sockfd,server-&gt;ai_addr,server-&gt;ai_addrlen)==-1){
          continue;
      }
      if(print){
          printf(&quot;Socket successfully connected\n&quot;);
      }
      break;
  }
      
  if(!connectFlag){
      printf(&quot;Could not connect to server %s.\n&quot;,HOSTNAME);
      close(sockfd);
      freeaddrinfo(result);
      return -1;
  }
  
  freeaddrinfo(result);
  </code></pre>
  <p>All this happens inside a function that reveivecs a parameter</p>
  <pre><code>int sockfd = socket(AF_INET,SOCK_STREAM,0);
  </code></pre>
  <p>from another function. Everything works out fine, the socket connects and I receive and send messages as expected.</p>
  <p>The problem is, when I check my created binary with</p>
  <pre><code>valgrind --leak-check=full --trace-children=yes ./binary
  </code></pre>
  <p>I get 3313 bytes are <em>still reachable</em>. When resolve the host manually and connect directly using the IP I get no leaks. I replaced getaddrinfo() with the older <a href="http://man7.org/linux/man-pages/man3/gethostbyname.3.html" rel="nofollow noreferrer">gethostbyname()</a> and got the exact same amount of still reachable bytes.</p>
  <p>How can I get rid of these leaks?</p>
  <p><strong>Valgrind output</strong></p>
  <pre><code>   % 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)
  </code></pre>
  <p>If I add the valgrind option --trace-children=yes valgrind checks a child process. I did not output this because the <em>leak</em> is happening in this parent process.</p>
  <p><strong>EDIT</strong></p>
  <p>It turned out we were not able to reproduce the valgrind output on other hardware. On this one server getaddrinfo() produced this valgrind output as well as gethostbyname(). We did not further observed where this behaviour might come from.</p>