Bug 378765

Summary: Invoke glibc cleanup when present (__libc_freeres)
Product: [Applications] Heaptrack Reporter: Maksim Golov <maxim.golov>
Component: generalAssignee: Milian Wolff <mail>
Status: RESOLVED FIXED    
Severity: normal    
Priority: NOR    
Version First Reported In: unspecified   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:
Attachments: Reproducer for strftime leak

Description Maksim Golov 2017-04-14 08:30:28 UTC
Created attachment 105019 [details]
Reproducer for strftime leak

Several functions like strftime allocate memory on the first use which is not cleaned up on shutdown by default. heaptrack reports such allocations as memory leaks.

glibc provides a cleanup method which can be used to release this memory before exit, see, for example, valgrind documentation.

Attached is a reproducer.

 $ g++ leak-strftime.cpp
 $ ./a.out
 $ heaptrack ./a.out
heaptrack output will be written to "/home/centos/work/heaptrack-eval/heaptrack.a.out.16784.gz"
starting application, this might take some time...
heaptrack stats:
	allocations:          	4
	leaked allocations:   	3
	temporary allocations:	0
Heaptrack finished! Now run the following to investigate the data:

  heaptrack_print "/home/centos/work/heaptrack-eval/heaptrack.a.out.16784.gz" | less
 $ heaptrack ./a.out noleak
heaptrack output will be written to "/home/centos/work/heaptrack-eval/heaptrack.a.out.16809.gz"
starting application, this might take some time...
heaptrack stats:
	allocations:          	4
	leaked allocations:   	0
	temporary allocations:	1
Heaptrack finished! Now run the following to investigate the data:

  heaptrack_print "/home/centos/work/heaptrack-eval/heaptrack.a.out.16809.gz" | less
Comment 1 Milian Wolff 2017-04-17 19:17:43 UTC
Git commit 3cb1b7fd2f4b3fd656758060582001f1e78c3e12 by Milian Wolff.
Committed on 17/04/2017 at 19:14.
Pushed by mwolff into branch 'master'.

Call libc and libstdc++ freeres functions in heaptrack_preload on exit

These functions are used by Valgrind already and can be used to force
a clean shutdown of libc and libstdc++. Both usually don't bother
freeing their global resources, which used to be reported as memory
leaks by heaptrack. By calling the freeres functions we now get a
clean shutdown of the libc_leaks.c example without any memory leaks
reported.

Thanks to Maxim Golov for pointing out this hidden functionality and
providing a test case.

M  +19   -0    src/track/heaptrack_preload.cpp
M  +2    -0    tests/manual/CMakeLists.txt
A  +30   -0    tests/manual/libc_leaks.c     [License: LGPL (v2+)]

https://commits.kde.org/heaptrack/3cb1b7fd2f4b3fd656758060582001f1e78c3e12
Comment 2 Milian Wolff 2021-09-24 14:43:48 UTC
Git commit 3e7405e6b83ea79bfaa7a1135d2cede2021394ae by Milian Wolff.
Committed on 24/09/2021 at 14:35.
Pushed by mwolff into branch 'master'.

Remove call to __libc_freeres and use builtin suppressions instead

Calling __libc_freeres is dangerous when we are not the last library
that gets its cleanup handler called. Sadly, there is no way to make
us reliably get into that last spot, see also:

https://sourceware.org/bugzilla/show_bug.cgi?id=28248

If we call __libc_freeres we might trigger cleanup of plugins too
early, which can then result in runtime crashes on exit:

```
(gdb) bt
#0  0x00007fffe9c4d340 in ?? ()
#1  0x00007ffff06033ac in ?? () from /usr/lib/qt/plugins/kf5/sonnet/sonnet_aspell.so
#2  0x00007ffff66c7ba2 in ?? () from /usr/lib/libQt5Core.so.5
#3  0x00007ffff66cbef5 in ?? () from /usr/lib/libQt5Core.so.5
#4  0x00007ffff66c9319 in ?? () from /usr/lib/libQt5Core.so.5
#5  0x00007ffff6076a8e in __cxa_finalize () from /usr/lib/libc.so.6
#6  0x00007ffff64ca478 in ?? () from /usr/lib/libQt5Core.so.5
#7  0x00007fffffffc730 in ?? ()
#8  0x00007ffff7fdd1a4 in _dl_fini () from /lib64/ld-linux-x86-64.so.2
```

Instead, we now ship with a (small for now, patches welcome!) list
of builtin suppressions which the user can disable if desired.

M  +5    -1    src/analyze/accumulatedtracedata.cpp
M  +1    -0    src/analyze/filterparameters.h
M  +7    -0    src/analyze/gui/gui.cpp
M  +15   -0    src/analyze/gui/mainwindow.cpp
M  +2    -0    src/analyze/gui/mainwindow.h
M  +4    -0    src/analyze/print/heaptrack_print.cpp
M  +17   -0    src/analyze/suppressions.cpp
M  +2    -0    src/analyze/suppressions.h
M  +0    -7    src/track/libheaptrack.cpp

https://invent.kde.org/sdk/heaptrack/commit/3e7405e6b83ea79bfaa7a1135d2cede2021394ae