Skip to content

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

@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