Uh oh!
There was an error while loading. Please reload this page.
gh-104690: thread_run() checks for tstate dangling pointer - #109056
Conversation
thread_run() of _threadmodule.c now calls _PyThreadState_CheckConsistency() to check if tstate is a dangling pointer. Rename ceval_gil.c is_tstate_valid() to _PyThreadState_CheckConsistency() to reuse it in _threadmodule.c.
vstinner
commented
Sep 7, 2023
This change provides a better error message rather than a blind crash. It should help debugging complicated crashes. Example: Patch to reintroduce the bug: diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index 49f34fcb9f..f5fc209e88 100644
--- a/Modules/_threadmodule.c+++ b/Modules/_threadmodule.c@@ -1158,11 +1161,13 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
"thread is not supported for isolated subinterpreters");
return NULL;
}
+#if 0
if (interp->finalizing) {
PyErr_SetString(PyExc_RuntimeError,
"can't create new thread at interpreter shutdown");
return NULL;
}
+#endif
struct bootstate *boot = PyMem_NEW(struct bootstate, 1);
if (boot == NULL) {Script importatexitimportthreadingdeft0():
passdeft1():
threading.Thread(target=t0).start()
deff():
threading.Thread(target=t1).start()
atexit.register(f)
exit() |
vstinner
commented
Sep 7, 2023
I don't think that it's related, but in a recent job on Windows x86, the following assertion failed while running test_threading() in a test worker process: Related code: staticvoidbind_tstate(PyThreadState*tstate)
{
assert(tstate!=NULL);
assert(tstate_is_alive(tstate) && !tstate->_status.bound); /// <=== HERE, line 245assert(!tstate->_status.unbound); // just in caseassert(!tstate->_status.bound_gilstate);
assert(tstate!=gilstate_tss_get(tstate->interp->runtime));
assert(!tstate->_status.active);
assert(tstate->thread_id==0);
assert(tstate->native_thread_id==0);I don't know if it would be worth it to repeat the See: #108987 |
vstinner
commented
Sep 7, 2023
Oh! I managed to reproduce issue #108987 on Windows 32-bit with my PR and I get: So apparently, thread_run() is called after PyInterpreterState_Delete() has been called! |
miss-islington
commented
Sep 8, 2023
Thanks @vstinner for the PR 🌮🎉.. I'm working now to backport this PR to: 3.11. |
miss-islington
commented
Sep 8, 2023
Thanks @vstinner for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12. |
miss-islington
commented
Sep 8, 2023
Sorry, @vstinner, I could not cleanly backport this to |
miss-islington
commented
Sep 8, 2023
Sorry, @vstinner, I could not cleanly backport this to |
…hon#109056) thread_run() of _threadmodule.c now calls _PyThreadState_CheckConsistency() to check if tstate is a dangling pointer when Python is built in debug mode. Rename ceval_gil.c is_tstate_valid() to _PyThreadState_CheckConsistency() to reuse it in _threadmodule.c. (cherry picked from commit f63d378)
bedevere-bot
commented
Sep 8, 2023
GH-109133 is a backport of this pull request to the 3.12 branch. |
bedevere-bot
commented
Sep 8, 2023
GH-109134 is a backport of this pull request to the 3.11 branch. |
…hon#109056) thread_run() of _threadmodule.c now calls _PyThreadState_CheckConsistency() to check if tstate is a dangling pointer when Python is built in debug mode. Rename ceval_gil.c is_tstate_valid() to _PyThreadState_CheckConsistency() to reuse it in _threadmodule.c. (cherry picked from commit f63d378)
…09056) (#109134) gh-104690: thread_run() checks for tstate dangling pointer (#109056) thread_run() of _threadmodule.c now calls _PyThreadState_CheckConsistency() to check if tstate is a dangling pointer when Python is built in debug mode. Rename ceval_gil.c is_tstate_valid() to _PyThreadState_CheckConsistency() to reuse it in _threadmodule.c. (cherry picked from commit f63d378)
…09056) (#109133) gh-104690: thread_run() checks for tstate dangling pointer (#109056) thread_run() of _threadmodule.c now calls _PyThreadState_CheckConsistency() to check if tstate is a dangling pointer when Python is built in debug mode. Rename ceval_gil.c is_tstate_valid() to _PyThreadState_CheckConsistency() to reuse it in _threadmodule.c. (cherry picked from commit f63d378)
thread_run() of _threadmodule.c now calls
_PyThreadState_CheckConsistency() to check if tstate is a dangling pointer.
Rename ceval_gil.c is_tstate_valid() to
_PyThreadState_CheckConsistency() to reuse it in _threadmodule.c.