Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Address review comments
  • Loading branch information
markshannon committed Aug 28, 2023
commit 9015dd07c28ef28b06571caeaad5707230705543
3 changes: 1 addition & 2 deletions Include/cpython/code.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ extern "C" {
/* Count of all monitoring events */
#define _PY_MONITORING_EVENTS 17

/* Table of which tools are active for each monitored event. */
/* Tables of which tools are active for each monitored event. */
typedef struct _Py_LocalMonitors {
uint8_t tools[_PY_MONITORING_LOCAL_EVENTS];
} _Py_LocalMonitors;

/* Table of which tools are active for each monitored event. */
typedef struct _Py_GlobalMonitors {
uint8_t tools[_PY_MONITORING_UNGROUPED_EVENTS];
} _Py_GlobalMonitors;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Raise an exception when setting a non-local event (RAISE EXCEPTION_HANDLED,
Raise an exception when setting a non-local event (``RAISE``, ``EXCEPTION_HANDLED``,
etc.) in ``sys.monitoring.set_local_events``.

Fixes crash when tracing in recursive calls to Python classes.
27 changes: 14 additions & 13 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -1968,29 +1968,30 @@ do_monitor_exc(PyThreadState *tstate, _PyInterpreterFrame *frame,
return err;
}

static inline int
static inline bool
no_tools_for_global_event(PyThreadState *tstate, int event)
{
return tstate->interp->monitors.tools[event] == 0;
}

static inline bool
no_tools_for_local_event(PyThreadState *tstate, _PyInterpreterFrame *frame, int event)
{
assert(event < _PY_MONITORING_LOCAL_EVENTS);
_PyCoMonitoringData *data = _PyFrame_GetCode(frame)->_co_monitoring;
if (data) {
if (data->active_monitors.tools[event] == 0) {
return 1;
}
return data->active_monitors.tools[event] == 0;
}
else {
if (tstate->interp->monitors.tools[event] == 0) {
return 1;
}
return no_tools_for_global_event(tstate, event);
}
return 0;
}

static void
monitor_raise(PyThreadState *tstate, _PyInterpreterFrame *frame,
_Py_CODEUNIT *instr)
{
if (tstate->interp->monitors.tools[PY_MONITORING_EVENT_RAISE] == 0) {
if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_RAISE)) {
return;
}
do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_RAISE);
Expand All @@ -2000,7 +2001,7 @@ static void
monitor_reraise(PyThreadState *tstate, _PyInterpreterFrame *frame,
_Py_CODEUNIT *instr)
{
if (tstate->interp->monitors.tools[PY_MONITORING_EVENT_RERAISE] == 0) {
if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_RERAISE)) {
return;
}
do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_RERAISE);
Expand All @@ -2021,7 +2022,7 @@ monitor_unwind(PyThreadState *tstate,
_PyInterpreterFrame *frame,
_Py_CODEUNIT *instr)
{
if (tstate->interp->monitors.tools[PY_MONITORING_EVENT_PY_UNWIND] == 0) {
if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_PY_UNWIND)) {
return;
}
do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_PY_UNWIND);
Expand All @@ -2033,7 +2034,7 @@ monitor_handled(PyThreadState *tstate,
_PyInterpreterFrame *frame,
_Py_CODEUNIT *instr, PyObject *exc)
{
if (tstate->interp->monitors.tools[PY_MONITORING_EVENT_EXCEPTION_HANDLED] == 0) {
if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_EXCEPTION_HANDLED)) {
return 0;
}
return _Py_call_instrumentation_arg(tstate, PY_MONITORING_EVENT_EXCEPTION_HANDLED, frame, instr, exc);
Expand All @@ -2044,7 +2045,7 @@ monitor_throw(PyThreadState *tstate,
_PyInterpreterFrame *frame,
_Py_CODEUNIT *instr)
{
if (tstate->interp->monitors.tools[PY_MONITORING_EVENT_PY_THROW] == 0) {
if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_PY_THROW)) {
return;
}
do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_PY_THROW);
Expand Down
15 changes: 13 additions & 2 deletions Python/instrumentation.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ monitors_and(_Py_LocalMonitors a, _Py_LocalMonitors b)
}
#endif

/* The union of the *local* events in a and b.
* Global events like RAISE are ignored.
* Used for instrumentation, as only local
* events get instrumented.
*/
static inline _Py_LocalMonitors
local_union(_Py_GlobalMonitors a, _Py_LocalMonitors b)
{
Expand Down Expand Up @@ -1554,6 +1559,12 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp)
return 0;
}
int code_len = (int)Py_SIZE(code);
/* code->_co_firsttraceable >= code_len indicates
* that no instrumentation can be inserted.
* Exit early to avoid creating instuementation
* data for potential statically allocated code
* objects.
* See https://github.com/python/cpython/issues/108390 */
if (code->_co_firsttraceable >= code_len) {
return 0;
}
Expand Down Expand Up @@ -1710,9 +1721,9 @@ set_events(_Py_GlobalMonitors *m, int tool_id, _PyMonitoringEventSet events)
assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS);
for (int e = 0; e < _PY_MONITORING_UNGROUPED_EVENTS; e++) {
uint8_t *tools = &m->tools[e];
int val = (events >> e) & 1;
int active = (events >> e) & 1;
*tools &= ~(1 << tool_id);
*tools |= (val << tool_id);
*tools |= (active << tool_id);
}
}

Expand Down