Open Gerzer opened 1 year ago
cc @vstinner who worked on removing the startup leakages as far as I remember :)
Leaking detected by Address Santitizer as well:
=================================================================
==22370==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 267212 byte(s) in 100 object(s) allocated from:
#0 0x7f0a1c916808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x7f0a1c50d9e7 (/lib/x86_64-linux-gnu/libpython3.8.so.1.0+0x25a9e7)
Direct leak of 536 byte(s) in 1 object(s) allocated from:
#0 0x7f0a1c916808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x7f0a1c50d182 (/lib/x86_64-linux-gnu/libpython3.8.so.1.0+0x25a182)
Indirect leak of 25922 byte(s) in 26 object(s) allocated from:
#0 0x7f0a1c916808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x7f0a1c50d9e7 (/lib/x86_64-linux-gnu/libpython3.8.so.1.0+0x25a9e7)
SUMMARY: AddressSanitizer: 293670 byte(s) leaked in 127 allocation(s).
It's different if memory is allocated exactly once and never released explicitly by Py_Finalize(), or if each Py_Initialize() call allocates new memory. Most of remaining "leaks" are memory allocated exactly once and then never released by Py_Finalize().
There is still a work-in-progress to convert remaining stdlib extensions to multi-phase initialization. A recent example with _elementtree: https://github.com/python/cpython/commit/fee7a995a18589001a432cea365fd04bf8efb7c1
If you are curious, you should dig into the pymain_free() function of Modules/main.c to see memory not freed by Py_Finalize(), but freed by Py_RunMain().
Python 3.12 arrived with plenty of new sanitizer-reported errors :-( ( https://github.com/python/cpython/issues/113190 )
Bug Report
The following code leaks several hundred kilobytes with the latest libpython from the Ubuntu APT repository:
With libpython3.10, it consistently leaks 480 KB, whereas with libpython3.11, it consistently leaks 408 KB. (These are proper IEC power-of-10 kilobytes, not power-of-2 kibibytes.) I’ve verified this by running this code as a Clang-compiled dynamic executable through Valgrind.
Binary Images
libpython3.10 version:
libpython3.11 version:
Valgrind Reports
Environment