gh-115649: Copy the filename into main interpreter before intern in import.c#120315
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Test code:
Execute result:
In current main branch, when a single-phase extension (
_tkinteris an example) got imported, it'sinitfunction will be execute in the main interpreter, although the import statement is executed in the sub-interpreter.And there is a workaround code to intern the
filenameobject to the main interpreter's interned string dict:cpython/Python/import.c
Lines 1970 to 1973 in c3b6dbf
I think the
filenameis created in the sub-interpreter in this test code, and it's allocated with the sub-interpreter's obmalloc state, which will be freed when the sub-interpreter is destroyed by statement_interpreters.destroy(iid)in the test code.When the main interpreter shutdown, it will try to free the interned string dict, this will cause issues and crash the interpreter.
Using gdb to dump the call stack:
Please note that the
#12frame#12 0x00005555556ac9ad in dictkeys_decref (interp=interp@entry=0x555555b17798 <_PyRuntime+101656>, dk=dk@entry=0x555555c51800, use_qsbr=use_qsbr@entry=false) at Objects/dictobject.c:492, it's code is:cpython/Objects/dictobject.c
Line 492 in c3b6dbf
We can't inspect the value here because it's memory got destroyed already. But adding these codes to L492:
We can see that when the interpreter crashed, it's calling
_Py_Dealloconfilenamestring object:Clone the
filenameand re-create it on the main interpreter can avoid the crash.import _tkinterleads to shutdown crash #115649