@@ -696,29 +696,13 @@ instrument_per_instruction(PyCodeObject *code, int i)
696
696
* opcode_ptr = INSTRUMENTED_INSTRUCTION ;
697
697
}
698
698
699
- #ifndef NDEBUG
700
- static bool
701
- instruction_has_event (PyCodeObject * code , int offset )
702
- {
703
- _Py_CODEUNIT instr = _PyCode_CODE (code )[offset ];
704
- int opcode = instr .op .code ;
705
- if (opcode == INSTRUMENTED_LINE ) {
706
- opcode = code -> _co_monitoring -> lines [offset ].original_opcode ;
707
- }
708
- if (opcode == INSTRUMENTED_INSTRUCTION ) {
709
- opcode = code -> _co_monitoring -> per_instruction_opcodes [offset ];
710
- }
711
- return opcode_has_event (opcode );
712
- }
713
- #endif
714
-
715
699
static void
716
700
remove_tools (PyCodeObject * code , int offset , int event , int tools )
717
701
{
718
702
assert (event != PY_MONITORING_EVENT_LINE );
719
703
assert (event != PY_MONITORING_EVENT_INSTRUCTION );
720
- assert (event < PY_MONITORING_INSTRUMENTED_EVENTS );
721
- assert (instruction_has_event ( code , offset ));
704
+ assert (PY_MONITORING_IS_INSTRUMENTED_EVENT ( event ) );
705
+ assert (opcode_has_event ( _Py_GetBaseOpcode ( code , offset ) ));
722
706
_PyCoMonitoringData * monitoring = code -> _co_monitoring ;
723
707
if (monitoring && monitoring -> tools ) {
724
708
monitoring -> tools [offset ] &= ~tools ;
@@ -773,7 +757,7 @@ add_tools(PyCodeObject * code, int offset, int event, int tools)
773
757
{
774
758
assert (event != PY_MONITORING_EVENT_LINE );
775
759
assert (event != PY_MONITORING_EVENT_INSTRUCTION );
776
- assert (event < PY_MONITORING_INSTRUMENTED_EVENTS );
760
+ assert (PY_MONITORING_IS_INSTRUMENTED_EVENT ( event ) );
777
761
assert (code -> _co_monitoring );
778
762
if (code -> _co_monitoring &&
779
763
code -> _co_monitoring -> tools
@@ -915,7 +899,7 @@ get_tools_for_instruction(PyCodeObject * code, int i, int event)
915
899
event == PY_MONITORING_EVENT_C_RETURN );
916
900
event = PY_MONITORING_EVENT_CALL ;
917
901
}
918
- if (event < PY_MONITORING_INSTRUMENTED_EVENTS && monitoring -> tools ) {
902
+ if (PY_MONITORING_IS_INSTRUMENTED_EVENT ( event ) && monitoring -> tools ) {
919
903
tools = monitoring -> tools [i ];
920
904
}
921
905
else {
@@ -926,6 +910,25 @@ get_tools_for_instruction(PyCodeObject * code, int i, int event)
926
910
return tools ;
927
911
}
928
912
913
+ static const char * const event_names [] = {
914
+ [PY_MONITORING_EVENT_PY_START ] = "PY_START" ,
915
+ [PY_MONITORING_EVENT_PY_RESUME ] = "PY_RESUME" ,
916
+ [PY_MONITORING_EVENT_PY_RETURN ] = "PY_RETURN" ,
917
+ [PY_MONITORING_EVENT_PY_YIELD ] = "PY_YIELD" ,
918
+ [PY_MONITORING_EVENT_CALL ] = "CALL" ,
919
+ [PY_MONITORING_EVENT_LINE ] = "LINE" ,
920
+ [PY_MONITORING_EVENT_INSTRUCTION ] = "INSTRUCTION" ,
921
+ [PY_MONITORING_EVENT_JUMP ] = "JUMP" ,
922
+ [PY_MONITORING_EVENT_BRANCH ] = "BRANCH" ,
923
+ [PY_MONITORING_EVENT_C_RETURN ] = "C_RETURN" ,
924
+ [PY_MONITORING_EVENT_PY_THROW ] = "PY_THROW" ,
925
+ [PY_MONITORING_EVENT_RAISE ] = "RAISE" ,
926
+ [PY_MONITORING_EVENT_EXCEPTION_HANDLED ] = "EXCEPTION_HANDLED" ,
927
+ [PY_MONITORING_EVENT_C_RAISE ] = "C_RAISE" ,
928
+ [PY_MONITORING_EVENT_PY_UNWIND ] = "PY_UNWIND" ,
929
+ [PY_MONITORING_EVENT_STOP_ITERATION ] = "STOP_ITERATION" ,
930
+ };
931
+
929
932
static int
930
933
call_instrumentation_vector (
931
934
PyThreadState * tstate , int event ,
@@ -973,7 +976,18 @@ call_instrumentation_vector(
973
976
}
974
977
else {
975
978
/* DISABLE */
976
- remove_tools (code , offset , event , 1 << tool );
979
+ if (!PY_MONITORING_IS_INSTRUMENTED_EVENT (event )) {
980
+ PyErr_Format (PyExc_ValueError ,
981
+ "Cannot disable %s events. Callback removed." ,
982
+ event_names [event ]);
983
+ /* Clear tool to prevent infinite loop */
984
+ Py_CLEAR (interp -> monitoring_callables [tool ][event ]);
985
+ err = -1 ;
986
+ break ;
987
+ }
988
+ else {
989
+ remove_tools (code , offset , event , 1 << tool );
990
+ }
977
991
}
978
992
}
979
993
Py_DECREF (offset_obj );
@@ -1251,7 +1265,7 @@ initialize_tools(PyCodeObject *code)
1251
1265
assert (event > 0 );
1252
1266
}
1253
1267
assert (event >= 0 );
1254
- assert (event < PY_MONITORING_INSTRUMENTED_EVENTS );
1268
+ assert (PY_MONITORING_IS_INSTRUMENTED_EVENT ( event ) );
1255
1269
tools [i ] = code -> _co_monitoring -> active_monitors .tools [event ];
1256
1270
CHECK (tools [i ] != 0 );
1257
1271
}
@@ -2024,25 +2038,6 @@ add_power2_constant(PyObject *obj, const char *name, int i)
2024
2038
return err ;
2025
2039
}
2026
2040
2027
- static const char * const event_names [] = {
2028
- [PY_MONITORING_EVENT_PY_START ] = "PY_START" ,
2029
- [PY_MONITORING_EVENT_PY_RESUME ] = "PY_RESUME" ,
2030
- [PY_MONITORING_EVENT_PY_RETURN ] = "PY_RETURN" ,
2031
- [PY_MONITORING_EVENT_PY_YIELD ] = "PY_YIELD" ,
2032
- [PY_MONITORING_EVENT_CALL ] = "CALL" ,
2033
- [PY_MONITORING_EVENT_LINE ] = "LINE" ,
2034
- [PY_MONITORING_EVENT_INSTRUCTION ] = "INSTRUCTION" ,
2035
- [PY_MONITORING_EVENT_JUMP ] = "JUMP" ,
2036
- [PY_MONITORING_EVENT_BRANCH ] = "BRANCH" ,
2037
- [PY_MONITORING_EVENT_C_RETURN ] = "C_RETURN" ,
2038
- [PY_MONITORING_EVENT_PY_THROW ] = "PY_THROW" ,
2039
- [PY_MONITORING_EVENT_RAISE ] = "RAISE" ,
2040
- [PY_MONITORING_EVENT_EXCEPTION_HANDLED ] = "EXCEPTION_HANDLED" ,
2041
- [PY_MONITORING_EVENT_C_RAISE ] = "C_RAISE" ,
2042
- [PY_MONITORING_EVENT_PY_UNWIND ] = "PY_UNWIND" ,
2043
- [PY_MONITORING_EVENT_STOP_ITERATION ] = "STOP_ITERATION" ,
2044
- };
2045
-
2046
2041
/*[clinic input]
2047
2042
monitoring._all_events
2048
2043
[clinic start generated code]*/
0 commit comments