Bug 448991

Summary: leak on fedora 33 and higher in getaddrinfo
Product: [Developer tools] valgrind Reporter: Alex <alex>
Component: memcheckAssignee: Julian Seward <jseward>
Status: RESOLVED NOT A BUG    
Severity: normal CC: tom
Priority: NOR    
Version First Reported In: 3.18.1   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description Alex 2022-01-23 05:25:50 UTC
SUMMARY

Starting with 
Fedora 33 glibc-2.32-10.fc33.x86_64
NAME=Fedora
VERSION="33 (Container Image)"

Valgrind on Fedora 32 doesn't report the memory leak

valgrind reports  (See complete stack trace below )
...
==18==    by 0x401DE9F: strdup (strdup.c:42)
==18==    by 0x40184F4: _dl_load_cache_lookup (dl-cache.c:312)
...
on program exit
It looks to be related to:

getaddrinfo


STEPS TO REPRODUCE

```
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
  struct addrinfo hints;
  struct addrinfo *result;

  if (argc < 2) {
    fprintf(stderr, "Usage: %s host port...\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  memset(&hints, '\0', sizeof(struct addrinfo));
  hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
  hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */

  getaddrinfo(argv[1], argv[2], &hints, &result);
  freeaddrinfo(result);
  exit(EXIT_SUCCESS);
```
 compile with:
```
clang -g -o leak leak.c
valgrind --leak-check=full --trace-children=yes --show-leak-kinds=all ./leak archlinux.org 80
```

OBSERVED RESULT

leak


EXPECTED RESULT

no leaks as in fedora 32


SOFTWARE/OS VERSIONS
Windows: 
macOS: 
Linux/KDE Plasma: 
(available in About System)
KDE Plasma Version: 
KDE Frameworks Version: 
Qt Version: 

ADDITIONAL INFORMATION
==18== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==18== Command: /usr/bin/api --debug
==18== 
==18== 
==18== HEAP SUMMARY:
==18==     in use at exit: 5,061 bytes in 12 blocks
==18==   total heap usage: 121,783 allocs, 121,771 frees, 171,928,544 bytes allocated
==18== 
==18== 21 bytes in 1 blocks are still reachable in loss record 1 of 7
==18==    at 0x4839809: malloc (vg_replace_malloc.c:307)
==18==    by 0x401DE9F: malloc (rtld-malloc.h:56)
==18==    by 0x401DE9F: strdup (strdup.c:42)
==18==    by 0x40184F4: _dl_load_cache_lookup (dl-cache.c:312)
==18==    by 0x400A046: _dl_map_object (dl-load.c:2185)
==18==    by 0x400E694: openaux (dl-deps.c:64)
==18==    by 0x5139BB7: _dl_catch_exception (in /usr/lib64/libc-2.32.so)
==18==    by 0x400EADA: _dl_map_object_deps (dl-deps.c:248)
==18==    by 0x4014B09: dl_open_worker (dl-open.c:584)
==18==    by 0x5139BB7: _dl_catch_exception (in /usr/lib64/libc-2.32.so)
==18==    by 0x401460D: _dl_open (dl-open.c:864)
==18==    by 0x5138FE0: do_dlopen (in /usr/lib64/libc-2.32.so)
==18==    by 0x5139BB7: _dl_catch_exception (in /usr/lib64/libc-2.32.so)
==18== 
==18== 21 bytes in 1 blocks are still reachable in loss record 2 of 7
==18==    at 0x4839809: malloc (vg_replace_malloc.c:307)
==18==    by 0x400C8B8: UnknownInlinedFun (rtld-malloc.h:56)
==18==    by 0x400C8B8: _dl_new_object (dl-object.c:196)
==18==    by 0x400841A: _dl_map_object_from_fd (dl-load.c:1073)
==18==    by 0x4009B3A: _dl_map_object (dl-load.c:2319)
==18==    by 0x400E694: openaux (dl-deps.c:64)
==18==    by 0x5139BB7: _dl_catch_exception (in /usr/lib64/libc-2.32.so)
==18==    by 0x400EADA: _dl_map_object_deps (dl-deps.c:248)
==18==    by 0x4014B09: dl_open_worker (dl-open.c:584)
==18==    by 0x5139BB7: _dl_catch_exception (in /usr/lib64/libc-2.32.so)
==18==    by 0x401460D: _dl_open (dl-open.c:864)
==18==    by 0x5138FE0: do_dlopen (in /usr/lib64/libc-2.32.so)
==18==    by 0x5139BB7: _dl_catch_exception (in /usr/lib64/libc-2.32.so
Comment 1 Tom Hughes 2022-01-23 08:40:57 UTC
That's not a leak - as valgrind says that memory is still reachable. A leak is memory is unreachable because there are no pointers to it but it hasn't been freed.

What you're looking at is some sort of cache inside the dynamic linker.

Possibly it's a glibc bug, in that we deliberately call __libc_freeres to ask glibc to free it's internal resources at exit (which doesn't happen normally) but it's not a valgrind bug.
Comment 2 Alex 2022-01-23 19:44:56 UTC
(In reply to Tom Hughes from comment #1)
> That's not a leak - as valgrind says that memory is still reachable. A leak
> is memory is unreachable because there are no pointers to it but it hasn't
> been freed.
> 
> What you're looking at is some sort of cache inside the dynamic linker.
> 
> Possibly it's a glibc bug, in that we deliberately call __libc_freeres to
> ask glibc to free it's internal resources at exit (which doesn't happen
> normally) but it's not a valgrind bug.

Thanks I'll try to open a bug with glibc...