mirror of https://github.com/python/cpython
bpo-38631: Avoid Py_FatalError() in handle_legacy_finalizers() (GH-17266)
* Rename _PyGC_Initialize() to _PyGC_InitializeRuntime() * Add _PyGC_Init(): initialize _PyRuntime.gc.garbage list * Call _PyGC_Init() before _PyTypes_Init()
This commit is contained in:
parent
e0cd8aa70a
commit
444b39bb64
|
@ -57,6 +57,7 @@ extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
|
|||
|
||||
extern PyStatus _PyTypes_Init(void);
|
||||
extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
|
||||
extern PyStatus _PyGC_Init(struct pyruntimestate *runtime);
|
||||
|
||||
|
||||
/* Various internal finalizers */
|
||||
|
|
|
@ -144,7 +144,7 @@ struct _gc_runtime_state {
|
|||
Py_ssize_t long_lived_pending;
|
||||
};
|
||||
|
||||
PyAPI_FUNC(void) _PyGC_Initialize(struct _gc_runtime_state *);
|
||||
PyAPI_FUNC(void) _PyGC_InitializeRuntime(struct _gc_runtime_state *);
|
||||
|
||||
|
||||
/* Set the memory allocator of the specified domain to the default.
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "Python.h"
|
||||
#include "pycore_context.h"
|
||||
#include "pycore_initconfig.h"
|
||||
#include "pycore_object.h"
|
||||
#include "pycore_pymem.h"
|
||||
#include "pycore_pystate.h"
|
||||
|
@ -129,7 +130,7 @@ static PyObject *gc_str = NULL;
|
|||
#define GEN_HEAD(state, n) (&(state)->generations[n].head)
|
||||
|
||||
void
|
||||
_PyGC_Initialize(struct _gc_runtime_state *state)
|
||||
_PyGC_InitializeRuntime(struct _gc_runtime_state *state)
|
||||
{
|
||||
state->enabled = 1; /* automatic collection enabled? */
|
||||
|
||||
|
@ -151,6 +152,21 @@ _PyGC_Initialize(struct _gc_runtime_state *state)
|
|||
state->permanent_generation = permanent_generation;
|
||||
}
|
||||
|
||||
|
||||
PyStatus
|
||||
_PyGC_Init(_PyRuntimeState *runtime)
|
||||
{
|
||||
struct _gc_runtime_state *state = &runtime->gc;
|
||||
if (state->garbage == NULL) {
|
||||
state->garbage = PyList_New(0);
|
||||
if (state->garbage == NULL) {
|
||||
return _PyStatus_NO_MEMORY();
|
||||
}
|
||||
}
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
_gc_prev values
|
||||
---------------
|
||||
|
@ -905,13 +921,9 @@ handle_legacy_finalizers(struct _gc_runtime_state *state,
|
|||
PyGC_Head *finalizers, PyGC_Head *old)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
assert(state->garbage != NULL);
|
||||
|
||||
PyGC_Head *gc = GC_NEXT(finalizers);
|
||||
if (state->garbage == NULL) {
|
||||
state->garbage = PyList_New(0);
|
||||
if (state->garbage == NULL)
|
||||
Py_FatalError("gc couldn't create gc.garbage list");
|
||||
}
|
||||
for (; gc != finalizers; gc = GC_NEXT(gc)) {
|
||||
PyObject *op = FROM_GC(gc);
|
||||
|
||||
|
|
|
@ -558,9 +558,16 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
|
|||
|
||||
|
||||
static PyStatus
|
||||
pycore_init_types(void)
|
||||
pycore_init_types(_PyRuntimeState *runtime)
|
||||
{
|
||||
PyStatus status = _PyTypes_Init();
|
||||
PyStatus status;
|
||||
|
||||
status = _PyGC_Init(runtime);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _PyTypes_Init();
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
}
|
||||
|
@ -683,7 +690,7 @@ pyinit_config(_PyRuntimeState *runtime,
|
|||
config = &tstate->interp->config;
|
||||
*tstate_p = tstate;
|
||||
|
||||
status = pycore_init_types();
|
||||
status = pycore_init_types(runtime);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
}
|
||||
|
@ -1447,7 +1454,7 @@ new_interpreter(PyThreadState **tstate_p)
|
|||
}
|
||||
config = &interp->config;
|
||||
|
||||
status = pycore_init_types();
|
||||
status = pycore_init_types(runtime);
|
||||
|
||||
/* XXX The following is lax in error checking */
|
||||
PyObject *modules = PyDict_New();
|
||||
|
|
|
@ -58,7 +58,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
|
|||
runtime->open_code_userdata = open_code_userdata;
|
||||
runtime->audit_hook_head = audit_hook_head;
|
||||
|
||||
_PyGC_Initialize(&runtime->gc);
|
||||
_PyGC_InitializeRuntime(&runtime->gc);
|
||||
_PyEval_Initialize(&runtime->ceval);
|
||||
|
||||
PyPreConfig_InitPythonConfig(&runtime->preconfig);
|
||||
|
|
Loading…
Reference in New Issue