mirror of
https://github.com/python/cpython.git
synced 2025-11-11 22:55:08 +00:00
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
5 changed files with 32 additions and 12 deletions
|
|
@ -57,6 +57,7 @@ extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
|
||||||
|
|
||||||
extern PyStatus _PyTypes_Init(void);
|
extern PyStatus _PyTypes_Init(void);
|
||||||
extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
|
extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
|
||||||
|
extern PyStatus _PyGC_Init(struct pyruntimestate *runtime);
|
||||||
|
|
||||||
|
|
||||||
/* Various internal finalizers */
|
/* Various internal finalizers */
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ struct _gc_runtime_state {
|
||||||
Py_ssize_t long_lived_pending;
|
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.
|
/* Set the memory allocator of the specified domain to the default.
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_context.h"
|
#include "pycore_context.h"
|
||||||
|
#include "pycore_initconfig.h"
|
||||||
#include "pycore_object.h"
|
#include "pycore_object.h"
|
||||||
#include "pycore_pymem.h"
|
#include "pycore_pymem.h"
|
||||||
#include "pycore_pystate.h"
|
#include "pycore_pystate.h"
|
||||||
|
|
@ -129,7 +130,7 @@ static PyObject *gc_str = NULL;
|
||||||
#define GEN_HEAD(state, n) (&(state)->generations[n].head)
|
#define GEN_HEAD(state, n) (&(state)->generations[n].head)
|
||||||
|
|
||||||
void
|
void
|
||||||
_PyGC_Initialize(struct _gc_runtime_state *state)
|
_PyGC_InitializeRuntime(struct _gc_runtime_state *state)
|
||||||
{
|
{
|
||||||
state->enabled = 1; /* automatic collection enabled? */
|
state->enabled = 1; /* automatic collection enabled? */
|
||||||
|
|
||||||
|
|
@ -151,6 +152,21 @@ _PyGC_Initialize(struct _gc_runtime_state *state)
|
||||||
state->permanent_generation = permanent_generation;
|
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
|
_gc_prev values
|
||||||
---------------
|
---------------
|
||||||
|
|
@ -905,13 +921,9 @@ handle_legacy_finalizers(struct _gc_runtime_state *state,
|
||||||
PyGC_Head *finalizers, PyGC_Head *old)
|
PyGC_Head *finalizers, PyGC_Head *old)
|
||||||
{
|
{
|
||||||
assert(!PyErr_Occurred());
|
assert(!PyErr_Occurred());
|
||||||
|
assert(state->garbage != NULL);
|
||||||
|
|
||||||
PyGC_Head *gc = GC_NEXT(finalizers);
|
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)) {
|
for (; gc != finalizers; gc = GC_NEXT(gc)) {
|
||||||
PyObject *op = FROM_GC(gc);
|
PyObject *op = FROM_GC(gc);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -558,9 +558,16 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
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)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
@ -683,7 +690,7 @@ pyinit_config(_PyRuntimeState *runtime,
|
||||||
config = &tstate->interp->config;
|
config = &tstate->interp->config;
|
||||||
*tstate_p = tstate;
|
*tstate_p = tstate;
|
||||||
|
|
||||||
status = pycore_init_types();
|
status = pycore_init_types(runtime);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
@ -1447,7 +1454,7 @@ new_interpreter(PyThreadState **tstate_p)
|
||||||
}
|
}
|
||||||
config = &interp->config;
|
config = &interp->config;
|
||||||
|
|
||||||
status = pycore_init_types();
|
status = pycore_init_types(runtime);
|
||||||
|
|
||||||
/* XXX The following is lax in error checking */
|
/* XXX The following is lax in error checking */
|
||||||
PyObject *modules = PyDict_New();
|
PyObject *modules = PyDict_New();
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
|
||||||
runtime->open_code_userdata = open_code_userdata;
|
runtime->open_code_userdata = open_code_userdata;
|
||||||
runtime->audit_hook_head = audit_hook_head;
|
runtime->audit_hook_head = audit_hook_head;
|
||||||
|
|
||||||
_PyGC_Initialize(&runtime->gc);
|
_PyGC_InitializeRuntime(&runtime->gc);
|
||||||
_PyEval_Initialize(&runtime->ceval);
|
_PyEval_Initialize(&runtime->ceval);
|
||||||
|
|
||||||
PyPreConfig_InitPythonConfig(&runtime->preconfig);
|
PyPreConfig_InitPythonConfig(&runtime->preconfig);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue