-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-128679: Redesign tracemalloc locking #128888
Conversation
vstinner
commented
Jan 15, 2025
•
edited by bedevere-app
bot
Loading
edited by bedevere-app
bot
- 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.
- Issue: Race condition in tracemalloc causes segfaults #128679
* 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 withPyMutex
and_Py_thread_local
instead. - 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. |