From 349b36bf843f59ad6dc2ebae5169474b9654a5cf Mon Sep 17 00:00:00 2001 From: Neil Schemenauer Date: Wed, 28 Oct 2026 09:19:32 -0700 Subject: [PATCH] gh-159136: Keep eval-frame recorded function names alive Hold a strong reference to func_name in both recording hooks before PyList_Append can detach while acquiring the recording list lock. --- Modules/_testinternalcapi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 16be593763bf667..5b5516046fff407 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -1182,8 +1182,9 @@ record_eval(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc) assert(module != NULL); module_state *state = get_module_state(module); Py_DECREF(module); - int res = PyList_Append(state->record_list, - FT_ATOMIC_LOAD_PTR_ACQUIRE(func->func_name)); + PyObject *name = Py_NewRef(FT_ATOMIC_LOAD_PTR_ACQUIRE(func->func_name)); + int res = PyList_Append(state->record_list, name); + Py_DECREF(name); if (res < 0) { return NULL; } @@ -1244,8 +1245,9 @@ record_eval_interp(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc assert(module != NULL); module_state *state = get_module_state(module); Py_DECREF(module); - int res = PyList_Append(state->record_list, - FT_ATOMIC_LOAD_PTR_ACQUIRE(func->func_name)); + PyObject *name = Py_NewRef(FT_ATOMIC_LOAD_PTR_ACQUIRE(func->func_name)); + int res = PyList_Append(state->record_list, name); + Py_DECREF(name); if (res < 0) { return NULL; }