summaryrefslogtreecommitdiffstats
path: root/Include
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2024-06-14 19:29:09 (GMT)
committerGitHub <noreply@github.com>2024-06-14 19:29:09 (GMT)
commitb2e71ff4f8fa5b7d8117dd8125137aee3d01f015 (patch)
tree76ffcadb4db306b4776329e3cf197fe0cd7894bc /Include
parent05df063ad80becc1ba6bd07d67b55b5965f32375 (diff)
downloadcpython-b2e71ff4f8fa5b7d8117dd8125137aee3d01f015.zip
cpython-b2e71ff4f8fa5b7d8117dd8125137aee3d01f015.tar.gz
cpython-b2e71ff4f8fa5b7d8117dd8125137aee3d01f015.tar.bz2
gh-120161: Fix a Crash in the _datetime Module (gh-120182)
In gh-120009 I used an atexit hook to finalize the _datetime module's static types at interpreter shutdown. However, atexit hooks are executed very early in finalization, which is a problem in the few cases where a subclass of one of those static types is still alive until the final GC collection. The static builtin types don't have this probably because they are finalized toward the end, after the final GC collection. To avoid the problem for _datetime, I have applied a similar approach here. Also, credit goes to @mgorny and @neonene for the new tests. FYI, I would have liked to take a slightly cleaner approach with managed static types, but wanted to get a smaller fix in first for the sake of backporting. I'll circle back to the cleaner approach with a future change on the main branch.
Diffstat (limited to 'Include')
-rw-r--r--Include/internal/pycore_typeobject.h24
1 files changed, 15 insertions, 9 deletions
diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h
index bc295b1..32bd19d 100644
--- a/Include/internal/pycore_typeobject.h
+++ b/Include/internal/pycore_typeobject.h
@@ -17,11 +17,25 @@ extern "C" {
#define _Py_TYPE_BASE_VERSION_TAG (2<<16)
#define _Py_MAX_GLOBAL_TYPE_VERSION_TAG (_Py_TYPE_BASE_VERSION_TAG - 1)
+/* For now we hard-code this to a value for which we are confident
+ all the static builtin types will fit (for all builds). */
+#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES 200
+#define _Py_MAX_MANAGED_STATIC_EXT_TYPES 10
+#define _Py_MAX_MANAGED_STATIC_TYPES \
+ (_Py_MAX_MANAGED_STATIC_BUILTIN_TYPES + _Py_MAX_MANAGED_STATIC_EXT_TYPES)
+
struct _types_runtime_state {
/* Used to set PyTypeObject.tp_version_tag for core static types. */
// bpo-42745: next_version_tag remains shared by all interpreters
// because of static types.
unsigned int next_version_tag;
+
+ struct {
+ struct {
+ PyTypeObject *type;
+ int64_t interp_count;
+ } types[_Py_MAX_MANAGED_STATIC_TYPES];
+ } managed_static;
};
@@ -42,11 +56,6 @@ struct type_cache {
struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP];
};
-/* For now we hard-code this to a value for which we are confident
- all the static builtin types will fit (for all builds). */
-#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES 200
-#define _Py_MAX_MANAGED_STATIC_EXT_TYPES 10
-
typedef struct {
PyTypeObject *type;
int isbuiltin;
@@ -133,6 +142,7 @@ struct types_state {
extern PyStatus _PyTypes_InitTypes(PyInterpreterState *);
extern void _PyTypes_FiniTypes(PyInterpreterState *);
+extern void _PyTypes_FiniExtTypes(PyInterpreterState *interp);
extern void _PyTypes_Fini(PyInterpreterState *);
extern void _PyTypes_AfterFork(void);
@@ -171,10 +181,6 @@ extern managed_static_type_state * _PyStaticType_GetState(
PyAPI_FUNC(int) _PyStaticType_InitForExtension(
PyInterpreterState *interp,
PyTypeObject *self);
-PyAPI_FUNC(void) _PyStaticType_FiniForExtension(
- PyInterpreterState *interp,
- PyTypeObject *self,
- int final);
/* Like PyType_GetModuleState, but skips verification