[3.11] gh-106883 Fix deadlock in threaded application (#117332)

When using threaded applications, there is a high risk of a deadlock in
the interpreter. It's a lock ordering deadlock with HEAD_LOCK(&_PyRuntime); and the GIL.

By disabling the GC during the _PyThread_CurrentFrames() and
_PyThread_CurrentExceptions() calls fixes the issue.
This commit is contained in:
Diego Russo 2025-03-11 15:31:03 +00:00 committed by GitHub
parent f1897d312e
commit 6b37486184
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 93 additions and 0 deletions

View file

@ -1398,6 +1398,9 @@ _PyThread_CurrentFrames(void)
return NULL;
}
// gh-106883: Disable the GC as this can cause the interpreter to deadlock
int gc_was_enabled = PyGC_Disable();
/* for i in all interpreters:
* for t in all of i's thread states:
* if t's frame isn't NULL, map t's id to its frame
@ -1440,6 +1443,12 @@ fail:
done:
HEAD_UNLOCK(runtime);
// Once the runtime is released, the GC can be reenabled.
if (gc_was_enabled) {
PyGC_Enable();
}
return result;
}
@ -1459,6 +1468,9 @@ _PyThread_CurrentExceptions(void)
return NULL;
}
// gh-106883: Disable the GC as this can cause the interpreter to deadlock
int gc_was_enabled = PyGC_Disable();
/* for i in all interpreters:
* for t in all of i's thread states:
* if t's frame isn't NULL, map t's id to its frame
@ -1499,6 +1511,12 @@ fail:
done:
HEAD_UNLOCK(runtime);
// Once the runtime is released, the GC can be reenabled.
if (gc_was_enabled) {
PyGC_Enable();
}
return result;
}