Open nascheme opened 5 hours ago
This bug was introduced by gh-124865.
My analysis of the issue is that the tracerefs debugging logic gets confused when objects are shared between sub-interpreters. E.g. _PyRefchain_Trace()
and _Py_ForgetReference()
kind of implicitly assume that objects belong to a single interpreter (interp->object_state.refchain
is what stores the trace and it's per interpreter). Objects can be shared when the reload_singlephase_extension()
m_size == -1
case occurs. That makes the objects used by the extension become shared between all sub-interpreters importing that extension.
I'm not sure why interned strings are the only thing causing trace-refs failures. I would guess that other objects should also cause an issue since _Py_ForgetReference()
will fail if they are traced in a different interpreter. It could be worth constructing a test case that triggers that problem (if possible).
Indeed, it does seem possible to crash with shared objects other than strings. You just have to initialize in the right way and then finalize in the right order.
https://github.com/nascheme/cpython/tree/test_single_phase_shared
Crash report
What happened?
To run test:
Programs/_testembed test_audit_subinterpreter
.The program crashes with an assert failure:
Stack trace:
The object is a string that has been interned but not immortalized. Likely it is shared between sub-interpreters, using basic single-phase init and is therefore shared between multiple sub-interpreters.
The value of
_PyRefchain_IsTraced()
is false since it is ref-traced in a different interpreter.Quick and dirty fix for the crash:
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
No response