gh-128679: Redesign tracemalloc locking (#128888)

* Use TABLES_LOCK() to protect 'tracemalloc_config.tracing'.
* Hold TABLES_LOCK() longer while accessing tables.
* tracemalloc_realloc() and tracemalloc_free() no longer
  remove the trace on reentrant call.
* _PyTraceMalloc_Stop() unregisters _PyTraceMalloc_TraceRef().
* _PyTraceMalloc_GetTraces() sets the reentrant flag.
* tracemalloc_clear_traces_unlocked() sets the reentrant flag.
This commit is contained in:
Victor Stinner 2025-01-15 21:22:44 +01:00 committed by GitHub
parent 080f444a58
commit 36c5e3bcc2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 302 additions and 364 deletions

View file

@ -25,7 +25,7 @@ struct _PyTraceMalloc_Config {
} initialized;
/* Is tracemalloc tracing memory allocations?
Variable protected by the GIL */
Variable protected by the TABLES_LOCK(). */
int tracing;
/* limit of the number of frames in a traceback, 1 by default.
@ -85,14 +85,14 @@ struct _tracemalloc_runtime_state {
size_t peak_traced_memory;
/* Hash table used as a set to intern filenames:
PyObject* => PyObject*.
Protected by the GIL */
Protected by the TABLES_LOCK(). */
_Py_hashtable_t *filenames;
/* Buffer to store a new traceback in traceback_new().
Protected by the GIL. */
Protected by the TABLES_LOCK(). */
struct tracemalloc_traceback *traceback;
/* Hash table used as a set to intern tracebacks:
traceback_t* => traceback_t*
Protected by the GIL */
Protected by the TABLES_LOCK(). */
_Py_hashtable_t *tracebacks;
/* pointer (void*) => trace (trace_t*).
Protected by TABLES_LOCK(). */
@ -144,7 +144,7 @@ extern PyObject* _PyTraceMalloc_GetTraces(void);
extern PyObject* _PyTraceMalloc_GetObjectTraceback(PyObject *obj);
/* Initialize tracemalloc */
extern int _PyTraceMalloc_Init(void);
extern PyStatus _PyTraceMalloc_Init(void);
/* Start tracemalloc */
extern int _PyTraceMalloc_Start(int max_nframe);