gh-128679: Redesign tracemalloc locking#128888
Conversation
* Use TABLES_LOCK() to protect 'tracemalloc_config.tracing'. * Hold TABLES_LOCK() longer while accessing tables. * tracemalloc_realloc_gil() and tracemalloc_raw_realloc() 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 change cannot be backported to Python 3.12 which doesn't have the Anyway, I don't plan to backport this major redesign to Python 3.13 neither. |
Don't remove the trace if it's a reentrant call.
ZeroIntensity
left a comment
There was a problem hiding this comment.
This looks like a much better solution. A few notes:
- I think it's worth trying to migrate away from
PyThread, because it's a lot more difficult to work with than the modern APIs. We can go withPyMutexand_Py_thread_localinstead. - We need to be careful with holding locks while acquiring the GIL, because that can lead to lock-ordering deadlocks.
- I'll need to look into what kind of subinterpreter problems might come up because of
PyGILState_Ensure, as it doesn't work very well. What would happen if e.g. a thread callsPyTraceMalloc_Track, which sets the GILstate for the main interpreter, then enters a different interpreter?
Why not. It can be done afterwards.
Right. The order is: first get the GIL, and then call TABLES_LOCK().
This PR doesn't change that. But right, there should be corner cases when sub-interpreters are involved. |
Uh oh!
There was an error while loading. Please reload this page.