gh-139116: tracemalloc: Detach thread state when acquiring tables_lock (GH-139449)

* gh-139116: tracemalloc: Detach thread state when acquiring tables_lock

This prevents a deadlock when:

- One thread is in `_PyTraceMalloc_Stop`, with `TABLES_LOCK` held, calling
  `PyRefTracer_SetTracer` which wants to stop the world
- Another is thread in `PyTraceMalloc_Track`, just attached thread state, waiting
  for `TABLES_LOCK`

Detaching the thread state while waiting for `TABLES_LOCK` allows
`PyRefTracer_SetTracer` to stop the world.


Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
This commit is contained in:
Petr Viktorin 2025-09-30 16:43:49 +02:00 committed by GitHub
parent b2f5ad0c6d
commit 01157e0cdf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 3 additions and 1 deletions

View file

@ -36,7 +36,7 @@ static int _PyTraceMalloc_TraceRef(PyObject *op, PyRefTracerEvent event,
the GIL held from PyMem_RawFree(). It cannot acquire the lock because it
would introduce a deadlock in _PyThreadState_DeleteCurrent(). */
#define tables_lock _PyRuntime.tracemalloc.tables_lock
#define TABLES_LOCK() PyMutex_LockFlags(&tables_lock, _Py_LOCK_DONT_DETACH)
#define TABLES_LOCK() PyMutex_Lock(&tables_lock)
#define TABLES_UNLOCK() PyMutex_Unlock(&tables_lock)