Skip to content

Deadlock when calling PyGILState_Ensure() from a fresh C thread #96071

Closed
@tom-pytel

Description

@tom-pytel

Bug report

This used to work with py 3.8, 3.9 and 3.10 but now fails. The failure is due to a deadlock condition due to the move of an alloc from before a HEAD_LOCK() to after causing a recursive call to PyGILState_Ensure() which eventually deadlocks on the HEAD_LOCK().

The following is a trace of calls from the initial call to PyGILState_Ensure() to the eventual deadlock:

pystate:PyGILState_Ensure()
pystate:PyThreadState_New()
pystate:new_threadstate()
  HEAD_LOCK()  <-- Initial head locked, the alloc_threadstate() call below used to happen before this in previous versions of Python.
pystate:alloc_threadstate()
obmalloc:PyMem_RawCalloc()
_tracemalloc:_PyMem_Raw.calloc()
_tracemalloc:tracemalloc_raw_calloc()
  get_reentrant() = 0
  set_reenterant(1)
pystate:PyGILState_Ensure()
pystate:PyThreadState_New()
pystate:new_threadstate()
  HEAD_LOCK()  <--   DEADLOCK HERE!

Steps to reproduce: In a Python C extension module, create a C thread then try to call PyGILState_Ensure() in that thread with no previous existing Python threadstate.

Your environment

Python 3.11.0rc1
Linux tom-VirtualBox 5.15.0-46-generic #49~20.04.1-Ubuntu SMP Thu Aug 4 19:15:44 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Metadata

Metadata

Labels

3.11only security fixes3.12only security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions