Three bugs in the cross-interpreter subsystem:
- _ensure_notshareableerror (crossinterp_exceptions.h:85): Missing
returnafter_PyErr_SetRaisedExceptionstealsctxref. Falls through to code using freed pointer. - _PyXI_UnwrapNotShareableError (crossinterp_data_lookup.h:102): Exception removed from thread state via
_PyErr_GetRaisedException, then_PyXI_InitFailurefails → exception leaked, thread error indicator cleared. - _pop_preserved (crossinterp.c:2968): Inner
_PyXI_namespace *xidatashadows outer.goto errorcleanup checks outer (NULL) variable → inner allocation leaked.
import _interpchannels as ch, sys
cid = ch.create()
before = sys.gettotalrefcount()
for i in range(10000):
try:
ch.send(cid, lambda: None, blocking=False)
except Exception:
pass
after = sys.gettotalrefcount()
ch.destroy(cid)
print(f"Leaked {after - before} refs (~{(after-before)//10000}/send)")