diff options
author | Victor Stinner <vstinner@python.org> | 2020-03-24 16:12:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-24 16:12:19 (GMT) |
commit | e97c8b0688bc62959ced477d842fcd37992ef649 (patch) | |
tree | 37a1e00c1de91f00398aaa17c18f84057106e8ca /Python | |
parent | 21bee0bd71e1ad270274499f9f58194ebb52e236 (diff) | |
download | cpython-e97c8b0688bc62959ced477d842fcd37992ef649.zip cpython-e97c8b0688bc62959ced477d842fcd37992ef649.tar.gz cpython-e97c8b0688bc62959ced477d842fcd37992ef649.tar.bz2 |
bpo-20526: Fix PyThreadState_Clear(): don't decref frame (GH-19120) (GH-19136)
PyThreadState.frame is a borrowed reference, not a strong reference:
PyThreadState_Clear() must not call Py_CLEAR(tstate->frame).
Remove test_threading.test_warnings_at_exit(): we cannot warranty
that the Python thread state of daemon threads is cleared in a
reliable way during Python shutdown.
(cherry picked from commit 5804f878e779712e803be927ca8a6df389d82cdf)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/pystate.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/Python/pystate.c b/Python/pystate.c index 9f99060..3e10855 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -762,11 +762,19 @@ PyThreadState_Clear(PyThreadState *tstate) { int verbose = tstate->interp->config.verbose; - if (verbose && tstate->frame != NULL) + if (verbose && tstate->frame != NULL) { + /* bpo-20526: After the main thread calls + _PyRuntimeState_SetFinalizing() in Py_FinalizeEx(), threads must + exit when trying to take the GIL. If a thread exit in the middle of + _PyEval_EvalFrameDefault(), tstate->frame is not reset to its + previous value. It is more likely with daemon threads, but it can + happen with regular threads if threading._shutdown() fails + (ex: interrupted by CTRL+C). */ fprintf(stderr, "PyThreadState_Clear: warning: thread still has a frame\n"); + } - Py_CLEAR(tstate->frame); + /* Don't clear tstate->frame: it is a borrowed reference */ Py_CLEAR(tstate->dict); Py_CLEAR(tstate->async_exc); |