mirror of
https://github.com/python/cpython.git
synced 2026-04-14 07:41:00 +00:00
gh-144763: Fix race conditions in tracemalloc (#144779)
Avoid PyUnstable_InterpreterFrame_GetLine() since it uses a critical
section which can lead to a deadlock.
_PyTraceMalloc_Stop() now also calls PyRefTracer_SetTracer() without
holding TABLES_LOCK() to prevent another deadlock.
(cherry picked from commit 83f4fffe3d)
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
parent
2ae7c2fadf
commit
f67cf83a4e
1 changed files with 16 additions and 6 deletions
|
|
@ -224,13 +224,20 @@ tracemalloc_get_frame(_PyInterpreterFrame *pyframe, frame_t *frame)
|
|||
assert(PyStackRef_CodeCheck(pyframe->f_executable));
|
||||
frame->filename = &_Py_STR(anon_unknown);
|
||||
|
||||
int lineno = PyUnstable_InterpreterFrame_GetLine(pyframe);
|
||||
int lineno = -1;
|
||||
PyCodeObject *code = _PyFrame_GetCode(pyframe);
|
||||
// PyUnstable_InterpreterFrame_GetLine() cannot but used, since it uses
|
||||
// a critical section which can trigger a deadlock.
|
||||
int lasti = _PyFrame_SafeGetLasti(pyframe);
|
||||
if (lasti >= 0) {
|
||||
lineno = _PyCode_SafeAddr2Line(code, lasti);
|
||||
}
|
||||
if (lineno < 0) {
|
||||
lineno = 0;
|
||||
}
|
||||
frame->lineno = (unsigned int)lineno;
|
||||
|
||||
PyObject *filename = filename = _PyFrame_GetCode(pyframe)->co_filename;
|
||||
PyObject *filename = code->co_filename;
|
||||
if (filename == NULL) {
|
||||
#ifdef TRACE_DEBUG
|
||||
tracemalloc_error("failed to get the filename of the code object");
|
||||
|
|
@ -853,7 +860,8 @@ _PyTraceMalloc_Stop(void)
|
|||
TABLES_LOCK();
|
||||
|
||||
if (!tracemalloc_config.tracing) {
|
||||
goto done;
|
||||
TABLES_UNLOCK();
|
||||
return;
|
||||
}
|
||||
|
||||
/* stop tracing Python memory allocations */
|
||||
|
|
@ -870,10 +878,12 @@ _PyTraceMalloc_Stop(void)
|
|||
raw_free(tracemalloc_traceback);
|
||||
tracemalloc_traceback = NULL;
|
||||
|
||||
(void)PyRefTracer_SetTracer(NULL, NULL);
|
||||
|
||||
done:
|
||||
TABLES_UNLOCK();
|
||||
|
||||
// Call it after TABLES_UNLOCK() since it calls _PyEval_StopTheWorldAll()
|
||||
// which would lead to a deadlock with TABLES_LOCK() which doesn't detach
|
||||
// the thread state.
|
||||
(void)PyRefTracer_SetTracer(NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue