Skip to content

Commit 9a6b60a

Browse files
gh-136870: fix data races in instrumentation of bytecode (#136994)
De-instrumenting code objects modifies the thread local bytecode for all threads as such, holding the critical section on the code object is not sufficient and leads to data races. Now, the de-instrumentation is now performed under a stop the world pause as such no thread races with executing the thread local bytecode while it is being de-instrumented.
1 parent 2456715 commit 9a6b60a

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix data races while de-instrumenting bytecode of code objects running concurrently in threads.

Python/instrumentation.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,9 +1190,10 @@ call_instrumentation_vector(
11901190
break;
11911191
}
11921192
else {
1193-
LOCK_CODE(code);
1193+
PyInterpreterState *interp = tstate->interp;
1194+
_PyEval_StopTheWorld(interp);
11941195
remove_tools(code, offset, event, 1 << tool);
1195-
UNLOCK_CODE();
1196+
_PyEval_StartTheWorld(interp);
11961197
}
11971198
}
11981199
}
@@ -1381,9 +1382,10 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
13811382
}
13821383
else {
13831384
/* DISABLE */
1384-
LOCK_CODE(code);
1385+
PyInterpreterState *interp = tstate->interp;
1386+
_PyEval_StopTheWorld(interp);
13851387
remove_line_tools(code, i, 1 << tool);
1386-
UNLOCK_CODE();
1388+
_PyEval_StartTheWorld(interp);
13871389
}
13881390
} while (tools);
13891391
Py_DECREF(line_obj);
@@ -1438,9 +1440,10 @@ _Py_call_instrumentation_instruction(PyThreadState *tstate, _PyInterpreterFrame*
14381440
}
14391441
else {
14401442
/* DISABLE */
1441-
LOCK_CODE(code);
1443+
PyInterpreterState *interp = tstate->interp;
1444+
_PyEval_StopTheWorld(interp);
14421445
remove_per_instruction_tools(code, offset, 1 << tool);
1443-
UNLOCK_CODE();
1446+
_PyEval_StartTheWorld(interp);
14441447
}
14451448
}
14461449
Py_DECREF(offset_obj);
@@ -2995,9 +2998,10 @@ branch_handler_vectorcall(
29952998
// Orphaned NOT_TAKEN -- Jump removed by the compiler
29962999
return res;
29973000
}
2998-
LOCK_CODE(code);
3001+
PyInterpreterState *interp = _PyInterpreterState_GET();
3002+
_PyEval_StopTheWorld(interp);
29993003
remove_tools(code, offset, other_event, 1 << self->tool_id);
3000-
UNLOCK_CODE();
3004+
_PyEval_StartTheWorld(interp);
30013005
}
30023006
return res;
30033007
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy