summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorTian Gao <gaogaotiantian@hotmail.com>2023-05-03 09:51:47 (GMT)
committerGitHub <noreply@github.com>2023-05-03 09:51:47 (GMT)
commitbcea36f8db9ad4fd542b38997e065987e829cb9f (patch)
tree5334aef7b551bedd924026e972710d0b9d9e7b92 /Python
parent0a5cd984b215f28d3c205eadf0daf201b3388c90 (diff)
downloadcpython-bcea36f8db9ad4fd542b38997e065987e829cb9f.zip
cpython-bcea36f8db9ad4fd542b38997e065987e829cb9f.tar.gz
cpython-bcea36f8db9ad4fd542b38997e065987e829cb9f.tar.bz2
gh-103845: Remove line & instruction instrumentations before adding them back (GH-103851)
Diffstat (limited to 'Python')
-rw-r--r--Python/instrumentation.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/Python/instrumentation.c b/Python/instrumentation.c
index c5bbbda..a142324 100644
--- a/Python/instrumentation.c
+++ b/Python/instrumentation.c
@@ -1477,25 +1477,25 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp)
}
}
}
- uint8_t new_line_tools = new_events.tools[PY_MONITORING_EVENT_LINE];
+
+ // GH-103845: We need to remove both the line and instruction instrumentation before
+ // adding new ones, otherwise we may remove the newly added instrumentation.
+
uint8_t removed_line_tools = removed_events.tools[PY_MONITORING_EVENT_LINE];
- if (new_line_tools | removed_line_tools) {
+ uint8_t removed_per_instruction_tools = removed_events.tools[PY_MONITORING_EVENT_INSTRUCTION];
+
+ if (removed_line_tools) {
_PyCoLineInstrumentationData *line_data = code->_co_monitoring->lines;
for (int i = code->_co_firsttraceable; i < code_len;) {
if (line_data[i].original_opcode) {
if (removed_line_tools) {
remove_line_tools(code, i, removed_line_tools);
}
- if (new_line_tools) {
- add_line_tools(code, i, new_line_tools);
- }
}
i += instruction_length(code, i);
}
}
- uint8_t new_per_instruction_tools = new_events.tools[PY_MONITORING_EVENT_INSTRUCTION];
- uint8_t removed_per_instruction_tools = removed_events.tools[PY_MONITORING_EVENT_INSTRUCTION];
- if (new_per_instruction_tools | removed_per_instruction_tools) {
+ if (removed_per_instruction_tools) {
for (int i = code->_co_firsttraceable; i < code_len;) {
int opcode = _Py_GetBaseOpcode(code, i);
if (opcode == RESUME || opcode == END_FOR) {
@@ -1505,6 +1505,31 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp)
if (removed_per_instruction_tools) {
remove_per_instruction_tools(code, i, removed_per_instruction_tools);
}
+ i += instruction_length(code, i);
+ }
+ }
+
+ uint8_t new_line_tools = new_events.tools[PY_MONITORING_EVENT_LINE];
+ uint8_t new_per_instruction_tools = new_events.tools[PY_MONITORING_EVENT_INSTRUCTION];
+
+ if (new_line_tools) {
+ _PyCoLineInstrumentationData *line_data = code->_co_monitoring->lines;
+ for (int i = code->_co_firsttraceable; i < code_len;) {
+ if (line_data[i].original_opcode) {
+ if (new_line_tools) {
+ add_line_tools(code, i, new_line_tools);
+ }
+ }
+ i += instruction_length(code, i);
+ }
+ }
+ if (new_per_instruction_tools) {
+ for (int i = code->_co_firsttraceable; i < code_len;) {
+ int opcode = _Py_GetBaseOpcode(code, i);
+ if (opcode == RESUME || opcode == END_FOR) {
+ i += instruction_length(code, i);
+ continue;
+ }
if (new_per_instruction_tools) {
add_per_instruction_tools(code, i, new_per_instruction_tools);
}