Repository navigation
Avoid memory leak in _pop_preserved() #147998
Description
Bug report
Bug description:
Inspired by gh-147960, I asked Claude Code (full disclosure), using @devdanzin's https://github.com/devdanzin/code-review-toolkit, to find more similar blunders. I think that this kind of mechanical omissions are ideal matches for LLM.
While I could not find exact missing PyMem_RawFree() and I do not agree with other (tortured) findings, there was a real one:
Line 2968 in 7817651
| _PyXI_namespace *xidata = _create_sharedns(session->_preserved); |
Line 2991 in 7817651
| if (xidata != NULL) { |
The xidata seems to be shadowed inside the else, and the error: path does not see it.
Reproduction
[130] 2026-04-02T19:53:24.286652120+0000 maurycy@weiss /home/maurycy/cpython (main) % ./python.exe -m test --single-process test_interpreters -m 'test_callable_requires_frame'
Using random seed: 2805989155
0:00:00 load avg: 1.02 Run 1 test sequentially in a single process
0:00:00 load avg: 1.02 [1/1] test_interpreters
0:00:00 load avg: 1.02 [1/1] test_interpreters passed
== Tests result: SUCCESS ==
1 test OK.
Total duration: 167 ms
Total tests: run=1 (filtered)
Total test files: run=1/1 (filtered)
Result: SUCCESS
=================================================================
==99950==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 192 byte(s) in 3 object(s) allocated from:
#0 0xaaaab6763810 in calloc (/home/maurycy/cpython/python.exe+0x343810) (BuildId: 1fbad198f97060c46a5d9d2231aca43704eee88e)
#1 0xaaaab6a3f4a0 in _PyMem_DebugRawAlloc /home/maurycy/cpython/Objects/obmalloc.c:3040:24
#2 0xaaaab6a3f4a0 in _PyMem_DebugRawCalloc /home/maurycy/cpython/Objects/obmalloc.c:3085:12
#3 0xaaaab6ccb5e0 in _sharedns_alloc /home/maurycy/cpython/Python/crossinterp.c:2277:27
#4 0xaaaab6ccb5e0 in _create_sharedns /home/maurycy/cpython/Python/crossinterp.c:2341:27
on CC=clang CXX=clang++ ./configure --with-pydebug --with-address-sanitizer --without-pymalloc -without-mimalloc build.
Another (Claude Code's) reproduction:
https://gist.github.com/maurycy/17e5aae1c8c665118c7980f373494e6e
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Activity
serhiy-storchaka commentedon Apr 2, 2026
The same code exists in 3.14. What about 3.13? Does it have such bug in other code?
maurycy commentedon Apr 2, 2026
@serhiy-storchaka
This is when this line was added:
https://github.com/python/cpython/pull/133484/changes#diff-88c171bf6a3ab394012cb7af2d9929543d379573ff46279de7ad38d4e7a12c54R2784
No backport to 3.13:
https://github.com/python/cpython/blob/3.13/Python/crossinterp.c
Do you mean more shadowings in other places? It reported lots stuff but I didn't immediately agree with it and don't want to be responsible (yet? until I review.)
maurycy commentedon May 3, 2026
@serhiy-storchaka Do you want to merge? (I’m going through my backlog.)
gh-147998: Fix possible memory leak in _pop_preserved (crossinterp.c) (…
serhiy-storchaka commentedon May 4, 2026
Thank you for your contribution @maurycy.
serhiy-storchaka commentedon May 4, 2026
I meant that while the exact form of these lines is new in 3.14, was there other code replaced but these lines and did it suffer from the same error? It could be a new bug introduced in new code, but it could also be an old bug that survived refactoring.
[3.14] gh-147998: Fix possible memory leak in _pop_preserved (crossin…
maurycy commentedon May 4, 2026
@serhiy-storchaka Thank you for clarification
I don't see it before
https://github.com/python/cpython/pull/135369/changes#diff-88c171bf6a3ab394012cb7af2d9929543d379573ff46279de7ad38d4e7a12c54R2977
in the original PR:
https://github.com/python/cpython/pull/133484/changes#diff-88c171bf6a3ab394012cb7af2d9929543d379573ff46279de7ad38d4e7a12c54R2785
serhiy-storchaka commentedon May 4, 2026
Thank you for confirmation.