diff --git a/Include/internal/pycore_initconfig.h b/Include/internal/pycore_initconfig.h index 6439101ff390ae4..d6ed2fbc52a702e 100644 --- a/Include/internal/pycore_initconfig.h +++ b/Include/internal/pycore_initconfig.h @@ -22,7 +22,7 @@ struct pyruntimestate; #endif #define _PyStatus_OK() \ - (PyStatus){._type = _PyStatus_TYPE_OK,} + (PyStatus){._type = _PyStatus_TYPE_OK} /* other fields are set to 0 */ #define _PyStatus_ERR(ERR_MSG) \ (PyStatus){ \ diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index d842816e6735534..daa06ebfbf91a48 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -182,7 +182,7 @@ _PyType_HasFeature(PyTypeObject *type, unsigned long feature) { extern void _PyType_InitCache(PyInterpreterState *interp); -extern void _PyObject_InitState(PyInterpreterState *interp); +extern PyStatus _PyObject_InitState(PyInterpreterState *interp); extern void _PyObject_FiniState(PyInterpreterState *interp); extern bool _PyRefchain_IsTraced(PyInterpreterState *interp, PyObject *obj); diff --git a/Objects/object.c b/Objects/object.c index a4d7111a686bda2..7aeda50e9b27574 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2034,7 +2034,7 @@ PyObject _Py_NotImplementedStruct = { }; -void +PyStatus _PyObject_InitState(PyInterpreterState *interp) { #ifdef Py_TRACE_REFS @@ -2048,9 +2048,10 @@ _PyObject_InitState(PyInterpreterState *interp) _Py_hashtable_hash_ptr, _Py_hashtable_compare_direct, NULL, NULL, &alloc); if (REFCHAIN(interp) == NULL) { - Py_FatalError("_PyObject_InitState() memory allocation failure"); + return _PyStatus_NO_MEMORY(); } #endif + return _PyStatus_OK(); } void diff --git a/Python/pystate.c b/Python/pystate.c index 4a8808f700eaa22..034482579f05803 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -426,13 +426,11 @@ init_runtime(_PyRuntimeState *runtime, Py_ssize_t unicode_next_index, PyThread_type_lock locks[NUMLOCKS]) { - if (runtime->_initialized) { - Py_FatalError("runtime already initialized"); - } - assert(!runtime->preinitializing && - !runtime->preinitialized && - !runtime->core_initialized && - !runtime->initialized); + assert(!runtime->preinitializing); + assert(!runtime->preinitialized); + assert(!runtime->core_initialized); + assert(!runtime->initialized); + assert(!runtime->_initialized); runtime->open_code_hook = open_code_hook; runtime->open_code_userdata = open_code_userdata; @@ -476,6 +474,7 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) // Py_Initialize() must be running again. // Reset to _PyRuntimeState_INIT. memcpy(runtime, &initial, sizeof(*runtime)); + assert(!runtime->_initialized); } if (gilstate_tss_init(runtime) != 0) { @@ -647,14 +646,14 @@ free_interpreter(PyInterpreterState *interp) main interpreter. We fix those fields here, in addition to the other dynamically initialized fields. */ -static void +static PyStatus init_interpreter(PyInterpreterState *interp, _PyRuntimeState *runtime, int64_t id, PyInterpreterState *next, PyThread_type_lock pending_lock) { if (interp->_initialized) { - Py_FatalError("interpreter already initialized"); + return _PyStatus_ERR("interpreter already initialized"); } assert(runtime != NULL); @@ -675,7 +674,10 @@ init_interpreter(PyInterpreterState *interp, memcpy(&interp->obmalloc.pools.used, temp, sizeof(temp)); } - _PyObject_InitState(interp); + PyStatus status = _PyObject_InitState(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } _PyEval_InitState(interp, pending_lock); _PyGC_InitState(&interp->gc); @@ -701,6 +703,7 @@ init_interpreter(PyInterpreterState *interp, } interp->f_opcode_trace_set = false; interp->_initialized = 1; + return _PyStatus_OK(); } PyInterpreterState * @@ -772,7 +775,15 @@ PyInterpreterState_New(void) } interpreters->head = interp; - init_interpreter(interp, runtime, id, old_head, pending_lock); + PyStatus status = init_interpreter(interp, runtime, + id, old_head, pending_lock); + if (_PyStatus_EXCEPTION(status)) { + const char *err_msg = status.err_msg; + if (!err_msg) { + err_msg = "failed to initialize the interpreter"; + } + Py_FatalError(err_msg); + } HEAD_UNLOCK(runtime); return interp;