summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2019-11-20 00:18:11 (GMT)
committerGitHub <noreply@github.com>2019-11-20 00:18:11 (GMT)
commit444b39bb64aa894d3f1831210a8ce40042a5a532 (patch)
tree994677ebd6160f8107ddd052c18813a9e61288ba
parente0cd8aa70a3ce19c3d3712568940aa0cbd9aa97b (diff)
downloadcpython-444b39bb64aa894d3f1831210a8ce40042a5a532.zip
cpython-444b39bb64aa894d3f1831210a8ce40042a5a532.tar.gz
cpython-444b39bb64aa894d3f1831210a8ce40042a5a532.tar.bz2
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()
-rw-r--r--Include/internal/pycore_pylifecycle.h1
-rw-r--r--Include/internal/pycore_pymem.h2
-rw-r--r--Modules/gcmodule.c24
-rw-r--r--Python/pylifecycle.c15
-rw-r--r--Python/pystate.c2
5 files changed, 32 insertions, 12 deletions
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index d89dbea..16baf10 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -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 */
diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h
index 535f99e..97d8fd9 100644
--- a/Include/internal/pycore_pymem.h
+++ b/Include/internal/pycore_pymem.h
@@ -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.
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index cb7a3de..d2e3937 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -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);
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 1bfc7c1..9739bb1 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -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();
diff --git a/Python/pystate.c b/Python/pystate.c
index b4b1247..06cc9a8 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -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);