@@ -702,29 +702,13 @@ instrument_per_instruction(PyCodeObject *code, int i)
702702 * opcode_ptr = INSTRUMENTED_INSTRUCTION ;
703703}
704704
705- #ifndef NDEBUG
706- static bool
707- instruction_has_event (PyCodeObject * code , int offset )
708- {
709- _Py_CODEUNIT instr = _PyCode_CODE (code )[offset ];
710- int opcode = instr .op .code ;
711- if (opcode == INSTRUMENTED_LINE ) {
712- opcode = code -> _co_monitoring -> lines [offset ].original_opcode ;
713- }
714- if (opcode == INSTRUMENTED_INSTRUCTION ) {
715- opcode = code -> _co_monitoring -> per_instruction_opcodes [offset ];
716- }
717- return opcode_has_event (opcode );
718- }
719- #endif
720-
721705static void
722706remove_tools (PyCodeObject * code , int offset , int event , int tools )
723707{
724708 assert (event != PY_MONITORING_EVENT_LINE );
725709 assert (event != PY_MONITORING_EVENT_INSTRUCTION );
726- assert (event < PY_MONITORING_INSTRUMENTED_EVENTS );
727- assert (instruction_has_event ( code , offset ));
710+ assert (PY_MONITORING_IS_INSTRUMENTED_EVENT ( event ) );
711+ assert (opcode_has_event ( _Py_GetBaseOpcode ( code , offset ) ));
728712 _PyCoMonitoringData * monitoring = code -> _co_monitoring ;
729713 if (monitoring && monitoring -> tools ) {
730714 monitoring -> tools [offset ] &= ~tools ;
@@ -779,7 +763,7 @@ add_tools(PyCodeObject * code, int offset, int event, int tools)
779763{
780764 assert (event != PY_MONITORING_EVENT_LINE );
781765 assert (event != PY_MONITORING_EVENT_INSTRUCTION );
782- assert (event < PY_MONITORING_INSTRUMENTED_EVENTS );
766+ assert (PY_MONITORING_IS_INSTRUMENTED_EVENT ( event ) );
783767 assert (code -> _co_monitoring );
784768 if (code -> _co_monitoring &&
785769 code -> _co_monitoring -> tools
@@ -919,7 +903,7 @@ get_tools_for_instruction(PyCodeObject *code, PyInterpreterState *interp, int i,
919903 event == PY_MONITORING_EVENT_C_RETURN );
920904 event = PY_MONITORING_EVENT_CALL ;
921905 }
922- if (event < PY_MONITORING_INSTRUMENTED_EVENTS ) {
906+ if (PY_MONITORING_IS_INSTRUMENTED_EVENT ( event ) ) {
923907 CHECK (is_version_up_to_date (code , interp ));
924908 CHECK (instrumentation_cross_checks (interp , code ));
925909 if (code -> _co_monitoring -> tools ) {
@@ -940,6 +924,26 @@ get_tools_for_instruction(PyCodeObject *code, PyInterpreterState *interp, int i,
940924 return tools ;
941925}
942926
927+ static const char * const event_names [] = {
928+ [PY_MONITORING_EVENT_PY_START ] = "PY_START" ,
929+ [PY_MONITORING_EVENT_PY_RESUME ] = "PY_RESUME" ,
930+ [PY_MONITORING_EVENT_PY_RETURN ] = "PY_RETURN" ,
931+ [PY_MONITORING_EVENT_PY_YIELD ] = "PY_YIELD" ,
932+ [PY_MONITORING_EVENT_CALL ] = "CALL" ,
933+ [PY_MONITORING_EVENT_LINE ] = "LINE" ,
934+ [PY_MONITORING_EVENT_INSTRUCTION ] = "INSTRUCTION" ,
935+ [PY_MONITORING_EVENT_JUMP ] = "JUMP" ,
936+ [PY_MONITORING_EVENT_BRANCH ] = "BRANCH" ,
937+ [PY_MONITORING_EVENT_C_RETURN ] = "C_RETURN" ,
938+ [PY_MONITORING_EVENT_PY_THROW ] = "PY_THROW" ,
939+ [PY_MONITORING_EVENT_RAISE ] = "RAISE" ,
940+ [PY_MONITORING_EVENT_RERAISE ] = "RERAISE" ,
941+ [PY_MONITORING_EVENT_EXCEPTION_HANDLED ] = "EXCEPTION_HANDLED" ,
942+ [PY_MONITORING_EVENT_C_RAISE ] = "C_RAISE" ,
943+ [PY_MONITORING_EVENT_PY_UNWIND ] = "PY_UNWIND" ,
944+ [PY_MONITORING_EVENT_STOP_ITERATION ] = "STOP_ITERATION" ,
945+ };
946+
943947static int
944948call_instrumentation_vector (
945949 PyThreadState * tstate , int event ,
@@ -984,7 +988,18 @@ call_instrumentation_vector(
984988 }
985989 else {
986990 /* DISABLE */
987- remove_tools (code , offset , event , 1 << tool );
991+ if (!PY_MONITORING_IS_INSTRUMENTED_EVENT (event )) {
992+ PyErr_Format (PyExc_ValueError ,
993+ "Cannot disable %s events. Callback removed." ,
994+ event_names [event ]);
995+ /* Clear tool to prevent infinite loop */
996+ Py_CLEAR (interp -> monitoring_callables [tool ][event ]);
997+ err = -1 ;
998+ break ;
999+ }
1000+ else {
1001+ remove_tools (code , offset , event , 1 << tool );
1002+ }
9881003 }
9891004 }
9901005 Py_DECREF (offset_obj );
@@ -1262,7 +1277,7 @@ initialize_tools(PyCodeObject *code)
12621277 assert (event > 0 );
12631278 }
12641279 assert (event >= 0 );
1265- assert (event < PY_MONITORING_INSTRUMENTED_EVENTS );
1280+ assert (PY_MONITORING_IS_INSTRUMENTED_EVENT ( event ) );
12661281 tools [i ] = code -> _co_monitoring -> active_monitors .tools [event ];
12671282 CHECK (tools [i ] != 0 );
12681283 }
@@ -2017,26 +2032,6 @@ add_power2_constant(PyObject *obj, const char *name, int i)
20172032 return err ;
20182033}
20192034
2020- static const char * const event_names [] = {
2021- [PY_MONITORING_EVENT_PY_START ] = "PY_START" ,
2022- [PY_MONITORING_EVENT_PY_RESUME ] = "PY_RESUME" ,
2023- [PY_MONITORING_EVENT_PY_RETURN ] = "PY_RETURN" ,
2024- [PY_MONITORING_EVENT_PY_YIELD ] = "PY_YIELD" ,
2025- [PY_MONITORING_EVENT_CALL ] = "CALL" ,
2026- [PY_MONITORING_EVENT_LINE ] = "LINE" ,
2027- [PY_MONITORING_EVENT_INSTRUCTION ] = "INSTRUCTION" ,
2028- [PY_MONITORING_EVENT_JUMP ] = "JUMP" ,
2029- [PY_MONITORING_EVENT_BRANCH ] = "BRANCH" ,
2030- [PY_MONITORING_EVENT_C_RETURN ] = "C_RETURN" ,
2031- [PY_MONITORING_EVENT_PY_THROW ] = "PY_THROW" ,
2032- [PY_MONITORING_EVENT_RAISE ] = "RAISE" ,
2033- [PY_MONITORING_EVENT_RERAISE ] = "RERAISE" ,
2034- [PY_MONITORING_EVENT_EXCEPTION_HANDLED ] = "EXCEPTION_HANDLED" ,
2035- [PY_MONITORING_EVENT_C_RAISE ] = "C_RAISE" ,
2036- [PY_MONITORING_EVENT_PY_UNWIND ] = "PY_UNWIND" ,
2037- [PY_MONITORING_EVENT_STOP_ITERATION ] = "STOP_ITERATION" ,
2038- };
2039-
20402035/*[clinic input]
20412036monitoring._all_events
20422037[clinic start generated code]*/
0 commit comments