From 6e761d73d19be686d15dd6a73b5c3749c3c801ae Mon Sep 17 00:00:00 2001 From: neonene <53406459+neonene@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:56:30 +0900 Subject: [PATCH] workaround main sub interp crashes --- Modules/_datetimemodule.c | 8 +++++++- Objects/typeobject.c | 18 +++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 78cc784628d917e..2a74219868d7e3d 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -7130,14 +7130,19 @@ callback_for_interp_exit(void *Py_UNUSED(data)) assert(_globals.interp_count > 0); PyMutex_Lock(&_globals.mutex); - int64_t final = !_globals.interp_count; _globals.interp_count -= 1; + int final = !_globals.interp_count; PyMutex_Unlock(&_globals.mutex); + /* Finish from parent to child */ for (size_t i = 0; i < Py_ARRAY_LENGTH(capi_types); i++) { PyTypeObject *type = capi_types[i]; _PyStaticType_FiniForExtension(interp, type, final); } + /* Clear indexes all at once */ + for (size_t i = 0; i < Py_ARRAY_LENGTH(capi_types); i++) { + capi_types[i]->tp_subclasses = NULL;; + } } static int @@ -7153,6 +7158,7 @@ init_static_types(PyInterpreterState *interp, int reloading) PyDateTime_TimeZoneType.tp_base = &PyDateTime_TZInfoType; PyDateTime_DateTimeType.tp_base = &PyDateTime_DateType; + /* Init from parent to child */ for (size_t i = 0; i < Py_ARRAY_LENGTH(capi_types); i++) { PyTypeObject *type = capi_types[i]; if (_PyStaticType_InitForExtension(interp, type) < 0) { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 09ba6d42fb330ca..51b04a400b39c4a 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -252,7 +252,7 @@ managed_static_type_state_clear(PyInterpreterState *interp, PyTypeObject *self, state->type = NULL; assert(state->tp_weaklist == NULL); // It was already cleared out. - if (final) { + if (final && isbuiltin) { managed_static_type_index_clear(self); } @@ -400,7 +400,9 @@ set_tp_bases(PyTypeObject *self, PyObject *bases) if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { // XXX tp_bases can probably be statically allocated for each // static builtin type. - assert(_Py_IsMainInterpreter(_PyInterpreterState_GET())); + PyInterpreterState *interp = _PyInterpreterState_GET(); + managed_static_type_state *state = managed_static_type_state_get(interp, self); + assert(!state->isbuiltin || _Py_IsMainInterpreter(interp)); assert(self->tp_bases == NULL); if (PyTuple_GET_SIZE(bases) == 0) { assert(self->tp_base == NULL); @@ -473,7 +475,9 @@ set_tp_mro(PyTypeObject *self, PyObject *mro) if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { // XXX tp_mro can probably be statically allocated for each // static builtin type. - assert(_Py_IsMainInterpreter(_PyInterpreterState_GET())); + PyInterpreterState *interp = _PyInterpreterState_GET(); + managed_static_type_state *state = managed_static_type_state_get(interp, self); + assert(!state->isbuiltin || _Py_IsMainInterpreter(interp)); assert(self->tp_mro == NULL); /* Other checks are done via set_tp_bases. */ _Py_SetImmortal(mro); @@ -7832,7 +7836,9 @@ static int type_ready_set_bases(PyTypeObject *type) { if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { - if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + managed_static_type_state *state = managed_static_type_state_get(interp, type); + if (state->isbuiltin && !_Py_IsMainInterpreter(interp)) { assert(lookup_tp_bases(type) != NULL); return 0; } @@ -7966,7 +7972,9 @@ type_ready_mro(PyTypeObject *type) ASSERT_TYPE_LOCK_HELD(); if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { - if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + managed_static_type_state *state = managed_static_type_state_get(interp, type); + if (state->isbuiltin && !_Py_IsMainInterpreter(interp)) { assert(lookup_tp_mro(type) != NULL); return 0; }