/* Support for legacy tracing on top of PEP 669 instrumentation
 * Provides callables to forward PEP 669 events to legacy events.
 */

#include "Python.h"
#include "pycore_audit.h"         // _PySys_Audit()
#include "pycore_ceval.h"         // export _PyEval_SetProfile()
#include "pycore_frame.h"         // PyFrameObject members
#include "pycore_interpframe.h"   // _PyFrame_GetCode()

#include "opcode.h"
#include <stddef.h>


typedef struct _PyLegacyEventHandler {
    PyObject_HEAD
    vectorcallfunc vectorcall;
    int event;
} _PyLegacyEventHandler;

#define _PyLegacyEventHandler_CAST(op)  ((_PyLegacyEventHandler *)(op))

/* The Py_tracefunc function expects the following arguments:
 *   obj: the trace object (PyObject *)
 *   frame: the current frame (PyFrameObject *)
 *   kind: the kind of event, see PyTrace_XXX #defines (int)
 *   arg: The arg (a PyObject *)
 */

static PyObject *
call_profile_func(_PyLegacyEventHandler *self, PyObject *arg)
{
    PyThreadState *tstate = _PyThreadState_GET();
    if (tstate->c_profilefunc == NULL) {
        Py_RETURN_NONE;
    }
    PyFrameObject *frame = PyEval_GetFrame();
    if (frame == NULL) {
        PyErr_SetString(PyExc_SystemError,
                        "Missing frame when calling profile function.");
        return NULL;
    }
    Py_INCREF(frame);
    int err = tstate->c_profilefunc(tstate->c_profileobj, frame, self->event, arg);
    Py_DECREF(frame);
    if (err) {
        return NULL;
    }
    Py_RETURN_NONE;
}

static PyObject *
sys_profile_start(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 2);
    return call_profile_func(self, Py_None);
}

static PyObject *
sys_profile_throw(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 3);
    return call_profile_func(self, Py_None);
}

static PyObject *
sys_profile_return(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 3);
    return call_profile_func(self, args[2]);
}

static PyObject *
sys_profile_unwind(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
     _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 3);
   return call_profile_func(self, NULL);
}

static PyObject *
sys_profile_call_or_return(
    PyObject *op, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(op);
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 4);
    PyObject *callable = args[2];
    if (PyCFunction_Check(callable)) {
        return call_profile_func(self, callable);
    }
    if (Py_TYPE(callable) == &PyMethodDescr_Type) {
        PyObject *self_arg = args[3];
        /* For backwards compatibility need to
         * convert to builtin method */

        /* If no arg, skip */
        if (self_arg == &_PyInstrumentation_MISSING) {
            Py_RETURN_NONE;
        }
        PyObject *meth = Py_TYPE(callable)->tp_descr_get(
            callable, self_arg, (PyObject*)Py_TYPE(self_arg));
        if (meth == NULL) {
            return NULL;
        }
        PyObject *res =  call_profile_func(self, meth);
        Py_DECREF(meth);
        return res;
    }
    Py_RETURN_NONE;
}

static int
set_opcode_trace_world_stopped(PyCodeObject *code, bool enable)
{
    _PyMonitoringEventSet events = 0;
    if (_PyMonitoring_GetLocalEvents(code, PY_MONITORING_SYS_TRACE_ID, &events) < 0) {
        return -1;
    }

    if (enable) {
        if (events & (1 << PY_MONITORING_EVENT_INSTRUCTION)) {
            return 0;
        }
        events |= (1 << PY_MONITORING_EVENT_INSTRUCTION);
    } else {
        if (!(events & (1 << PY_MONITORING_EVENT_INSTRUCTION))) {
            return 0;
        }
        events &= (~(1 << PY_MONITORING_EVENT_INSTRUCTION));
    }
    return _PyMonitoring_SetLocalEvents(code, PY_MONITORING_SYS_TRACE_ID, events);
}

int
_PyEval_SetOpcodeTrace(PyFrameObject *frame, bool enable)
{
    assert(frame != NULL);

    PyCodeObject *code = _PyFrame_GetCode(frame->f_frame);

#ifdef Py_GIL_DISABLED
    // First check if a change is necessary outside of the stop-the-world pause
    _PyMonitoringEventSet events = 0;
    if (_PyMonitoring_GetLocalEvents(code, PY_MONITORING_SYS_TRACE_ID, &events) < 0) {
        return -1;
    }
    int is_enabled = (events & (1 << PY_MONITORING_EVENT_INSTRUCTION)) != 0;
    if (is_enabled == enable) {
        return 0;  // No change needed
    }
#endif

    PyInterpreterState *interp = _PyInterpreterState_GET();
    _PyEval_StopTheWorld(interp);
    int res = set_opcode_trace_world_stopped(code, enable);
    _PyEval_StartTheWorld(interp);
    return res;
}

static PyObject *
call_trace_func(_PyLegacyEventHandler *self, PyObject *arg)
{
    PyThreadState *tstate = _PyThreadState_GET();
    if (tstate->c_tracefunc == NULL) {
        Py_RETURN_NONE;
    }
    PyFrameObject *frame = PyEval_GetFrame();
    if (frame == NULL) {
        PyErr_SetString(PyExc_SystemError,
                        "Missing frame when calling trace function.");
        return NULL;
    }
    if (frame->f_trace_opcodes) {
        if (_PyEval_SetOpcodeTrace(frame, true) != 0) {
            return NULL;
        }
    }

    Py_INCREF(frame);
    int err = tstate->c_tracefunc(tstate->c_traceobj, frame, self->event, arg);
    frame->f_lineno = 0;
    Py_DECREF(frame);
    if (err) {
        return NULL;
    }
    Py_RETURN_NONE;
}

static PyObject *
sys_trace_exception_func(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 3);
    PyObject *exc = args[2];
    assert(PyExceptionInstance_Check(exc));
    PyObject *type = (PyObject *)Py_TYPE(exc);
    PyObject *tb = PyException_GetTraceback(exc);
    if (tb == NULL) {
        tb = Py_NewRef(Py_None);
    }
    PyObject *tuple = PyTuple_Pack(3, type, exc, tb);
    Py_DECREF(tb);
    if (tuple == NULL) {
        return NULL;
    }
    PyObject *res = call_trace_func(self, tuple);
    Py_DECREF(tuple);
    return res;
}

static PyObject *
sys_trace_start(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 2);
    return call_trace_func(self, Py_None);
}

static PyObject *
sys_trace_throw(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 3);
    return call_trace_func(self, Py_None);
}

static PyObject *
sys_trace_unwind(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 3);
    return call_trace_func(self, NULL);
}

static PyObject *
sys_trace_return(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(!PyErr_Occurred());
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 3);
    assert(PyCode_Check(args[0]));
    PyObject *val = args[2];
    PyObject *res = call_trace_func(self, val);
    return res;
}

static PyObject *
sys_trace_yield(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 3);
    return call_trace_func(self, args[2]);
}

static PyObject *
sys_trace_instruction_func(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    assert(PyVectorcall_NARGS(nargsf) == 2);
    PyFrameObject *frame = PyEval_GetFrame();
    if (frame == NULL) {
        PyErr_SetString(PyExc_SystemError,
                        "Missing frame when calling trace function.");
        return NULL;
    }
    PyThreadState *tstate = _PyThreadState_GET();
    if (!tstate->c_tracefunc || !frame->f_trace_opcodes) {
        if (_PyEval_SetOpcodeTrace(frame, false) != 0) {
            return NULL;
        }
        Py_RETURN_NONE;
    }
    Py_INCREF(frame);
    int err = tstate->c_tracefunc(tstate->c_traceobj, frame, self->event, Py_None);
    frame->f_lineno = 0;
    Py_DECREF(frame);
    if (err) {
        return NULL;
    }
    Py_RETURN_NONE;
}

static PyObject *
trace_line(
    PyThreadState *tstate, _PyLegacyEventHandler *self,
    PyFrameObject *frame, int line
) {
    if (!frame->f_trace_lines) {
        Py_RETURN_NONE;
    }
    if (line < 0) {
        Py_RETURN_NONE;
    }
    Py_INCREF(frame);
    frame->f_lineno = line;
    int err = tstate->c_tracefunc(tstate->c_traceobj, frame, self->event, Py_None);
    frame->f_lineno = 0;
    Py_DECREF(frame);
    if (err) {
        return NULL;
    }
    Py_RETURN_NONE;
}

static PyObject *
sys_trace_line_func(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    PyThreadState *tstate = _PyThreadState_GET();
    if (tstate->c_tracefunc == NULL) {
        Py_RETURN_NONE;
    }
    assert(PyVectorcall_NARGS(nargsf) == 2);
    int line = PyLong_AsInt(args[1]);
    assert(line >= 0);
    PyFrameObject *frame = PyEval_GetFrame();
    if (frame == NULL) {
        PyErr_SetString(PyExc_SystemError,
                        "Missing frame when calling trace function.");
        return NULL;
    }
    assert(args[0] == (PyObject *)_PyFrame_GetCode(frame->f_frame));
    return trace_line(tstate, self, frame, line);
}

/* sys.settrace generates line events for all backward
 * edges, even if on the same line.
 * Handle that case here */
static PyObject *
sys_trace_jump_func(
    PyObject *callable, PyObject *const *args,
    size_t nargsf, PyObject *kwnames
) {
    _PyLegacyEventHandler *self = _PyLegacyEventHandler_CAST(callable);
    assert(kwnames == NULL);
    PyThreadState *tstate = _PyThreadState_GET();
    if (tstate->c_tracefunc == NULL) {
        Py_RETURN_NONE;
    }
    assert(PyVectorcall_NARGS(nargsf) == 3);
    int from = PyLong_AsInt(args[1])/sizeof(_Py_CODEUNIT);
    assert(from >= 0);
    int to = PyLong_AsInt(args[2])/sizeof(_Py_CODEUNIT);
    assert(to >= 0);
    if (to > from) {
        /* Forward jump */
        return &_PyInstrumentation_DISABLE;
    }
    PyCodeObject *code = (PyCodeObject *)args[0];
    assert(PyCode_Check(code));
    /* We can call _Py_Instrumentation_GetLine because we always set
    * line events for tracing */
    int to_line = _Py_Instrumentation_GetLine(code, code->_co_monitoring->lines, to);
    int from_line = _Py_Instrumentation_GetLine(code, code->_co_monitoring->lines, from);
    if (to_line != from_line) {
        /* Will be handled by target INSTRUMENTED_LINE */
        return &_PyInstrumentation_DISABLE;
    }
    PyFrameObject *frame = PyEval_GetFrame();
    if (frame == NULL) {
        PyErr_SetString(PyExc_SystemError,
                        "Missing frame when calling trace function.");
        return NULL;
    }
    if (!frame->f_trace_lines) {
        Py_RETURN_NONE;
    }
    return trace_line(tstate, self, frame, to_line);
}

PyTypeObject _PyLegacyEventHandler_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "sys.legacy_event_handler",
    sizeof(_PyLegacyEventHandler),
    .tp_vectorcall_offset = offsetof(_PyLegacyEventHandler, vectorcall),
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
        Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_DISALLOW_INSTANTIATION,
    .tp_call = PyVectorcall_Call,
};

static int
set_callbacks(int tool, vectorcallfunc vectorcall, int legacy_event, int event1, int event2)
{
    _PyLegacyEventHandler *callback =
        PyObject_NEW(_PyLegacyEventHandler, &_PyLegacyEventHandler_Type);
    if (callback == NULL) {
        return -1;
    }
    callback->vectorcall = vectorcall;
    callback->event = legacy_event;
    Py_XDECREF(_PyMonitoring_RegisterCallback(tool, event1, (PyObject *)callback));
    if (event2 >= 0) {
        Py_XDECREF(_PyMonitoring_RegisterCallback(tool, event2, (PyObject *)callback));
    }
    Py_DECREF(callback);
    return 0;
}

#ifndef NDEBUG
/* Ensure that tstate is valid: sanity check for PyEval_AcquireThread() and
   PyEval_RestoreThread(). Detect if tstate memory was freed. It can happen
   when a thread continues to run after Python finalization, especially
   daemon threads. */
static int
is_tstate_valid(PyThreadState *tstate)
{
    assert(!_PyMem_IsPtrFreed(tstate));
    assert(!_PyMem_IsPtrFreed(tstate->interp));
    return 1;
}
#endif

static int
setup_profile_callbacks(void *Py_UNUSED(arg))
{
    /* Setup PEP 669 monitoring callbacks and events. */
    if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID,
                      sys_profile_start, PyTrace_CALL,
                      PY_MONITORING_EVENT_PY_START,
                      PY_MONITORING_EVENT_PY_RESUME)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID,
                      sys_profile_throw, PyTrace_CALL,
                      PY_MONITORING_EVENT_PY_THROW, -1)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID,
                      sys_profile_return, PyTrace_RETURN,
                      PY_MONITORING_EVENT_PY_RETURN,
                      PY_MONITORING_EVENT_PY_YIELD)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID,
                      sys_profile_unwind, PyTrace_RETURN,
                      PY_MONITORING_EVENT_PY_UNWIND, -1)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID,
                      sys_profile_call_or_return, PyTrace_C_CALL,
                      PY_MONITORING_EVENT_CALL, -1)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID,
                      sys_profile_call_or_return, PyTrace_C_RETURN,
                      PY_MONITORING_EVENT_C_RETURN, -1)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID,
                      sys_profile_call_or_return, PyTrace_C_EXCEPTION,
                      PY_MONITORING_EVENT_C_RAISE, -1)) {
        return -1;
    }
    return 0;
}

static PyObject *
swap_profile_func_arg(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
{
    int delta = (func != NULL) - (tstate->c_profilefunc != NULL);
    tstate->c_profilefunc = func;
    PyObject *old_profileobj = tstate->c_profileobj;
    tstate->c_profileobj = Py_XNewRef(arg);
    tstate->interp->sys_profiling_threads += delta;
    assert(tstate->interp->sys_profiling_threads >= 0);
    return old_profileobj;
}

static int
set_monitoring_profile_events(PyInterpreterState *interp)
{
    uint32_t events = 0;
    if (interp->sys_profiling_threads) {
        events =
            (1 << PY_MONITORING_EVENT_PY_START) | (1 << PY_MONITORING_EVENT_PY_RESUME) |
            (1 << PY_MONITORING_EVENT_PY_RETURN) | (1 << PY_MONITORING_EVENT_PY_YIELD) |
            (1 << PY_MONITORING_EVENT_CALL) | (1 << PY_MONITORING_EVENT_PY_UNWIND) |
            (1 << PY_MONITORING_EVENT_PY_THROW);
    }
    return _PyMonitoring_SetEvents(PY_MONITORING_SYS_PROFILE_ID, events);
}

int
_PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
{
    assert(is_tstate_valid(tstate));
    /* The caller must hold a thread state */
    _Py_AssertHoldsTstate();

    /* Call _PySys_Audit() in the context of the current thread state,
       even if tstate is not the current thread state. */
    PyThreadState *current_tstate = _PyThreadState_GET();
    if (_PySys_Audit(current_tstate, "sys.setprofile", NULL) < 0) {
        return -1;
    }

    PyInterpreterState *interp = tstate->interp;
    if (_PyOnceFlag_CallOnce(&interp->sys_profile_once_flag,
                             setup_profile_callbacks, NULL) < 0) {
        return -1;
    }

    _PyEval_StopTheWorld(interp);
    PyObject *old_profileobj = swap_profile_func_arg(tstate, func, arg);
    int ret = set_monitoring_profile_events(interp);
    _PyEval_StartTheWorld(interp);
    Py_XDECREF(old_profileobj);  // needs to be decref'd outside of stop-the-world
    return ret;
}

int
_PyEval_SetProfileAllThreads(PyInterpreterState *interp, Py_tracefunc func, PyObject *arg)
{
    PyThreadState *current_tstate = _PyThreadState_GET();
    assert(is_tstate_valid(current_tstate));
    assert(current_tstate->interp == interp);

    if (_PySys_Audit(current_tstate, "sys.setprofile", NULL) < 0) {
        return -1;
    }

    if (_PyOnceFlag_CallOnce(&interp->sys_profile_once_flag,
                             setup_profile_callbacks, NULL) < 0) {
        return -1;
    }

    PyObject *old_profileobjs = NULL;
    _PyEval_StopTheWorld(interp);
    HEAD_LOCK(&_PyRuntime);
    Py_ssize_t num_thread_states = 0;
    _Py_FOR_EACH_TSTATE_UNLOCKED(interp, p) {
        num_thread_states++;
    }
    old_profileobjs = PyTuple_New(num_thread_states);
    if (old_profileobjs == NULL) {
        HEAD_UNLOCK(&_PyRuntime);
        _PyEval_StartTheWorld(interp);
        return -1;
    }
    _Py_FOR_EACH_TSTATE_UNLOCKED(interp, tstate) {
        PyObject *old = swap_profile_func_arg(tstate, func, arg);
        PyTuple_SET_ITEM(old_profileobjs, --num_thread_states, old);
    }
    HEAD_UNLOCK(&_PyRuntime);
    int ret = set_monitoring_profile_events(interp);
    _PyEval_StartTheWorld(interp);
    Py_XDECREF(old_profileobjs);  // needs to be decref'd outside of stop-the-world
    return ret;
}

static int
setup_trace_callbacks(void *Py_UNUSED(arg))
{
    /* Setup PEP 669 monitoring callbacks and events. */
    if (set_callbacks(PY_MONITORING_SYS_TRACE_ID,
                      sys_trace_start, PyTrace_CALL,
                      PY_MONITORING_EVENT_PY_START,
                      PY_MONITORING_EVENT_PY_RESUME)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_TRACE_ID,
                      sys_trace_throw, PyTrace_CALL,
                      PY_MONITORING_EVENT_PY_THROW, -1)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_TRACE_ID,
                      sys_trace_return, PyTrace_RETURN,
                      PY_MONITORING_EVENT_PY_RETURN, -1)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_TRACE_ID,
                      sys_trace_yield, PyTrace_RETURN,
                      PY_MONITORING_EVENT_PY_YIELD, -1)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_TRACE_ID,
                      sys_trace_exception_func, PyTrace_EXCEPTION,
                      PY_MONITORING_EVENT_RAISE,
                      PY_MONITORING_EVENT_STOP_ITERATION)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_TRACE_ID,
                      sys_trace_line_func, PyTrace_LINE,
                      PY_MONITORING_EVENT_LINE, -1)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_TRACE_ID,
                      sys_trace_unwind, PyTrace_RETURN,
                      PY_MONITORING_EVENT_PY_UNWIND, -1)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_TRACE_ID,
                      sys_trace_jump_func, PyTrace_LINE,
                      PY_MONITORING_EVENT_JUMP, -1)) {
        return -1;
    }
    if (set_callbacks(PY_MONITORING_SYS_TRACE_ID,
                      sys_trace_instruction_func, PyTrace_OPCODE,
                      PY_MONITORING_EVENT_INSTRUCTION, -1)) {
        return -1;
    }
    return 0;
}

static PyObject *
swap_trace_func_arg(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
{
    int delta = (func != NULL) - (tstate->c_tracefunc != NULL);
    tstate->c_tracefunc = func;
    PyObject *old_traceobj = tstate->c_traceobj;
    tstate->c_traceobj = Py_XNewRef(arg);
    tstate->interp->sys_tracing_threads += delta;
    assert(tstate->interp->sys_tracing_threads >= 0);
    return old_traceobj;
}

static int
set_monitoring_trace_events(PyInterpreterState *interp)
{
    uint32_t events = 0;
    if (interp->sys_tracing_threads) {
        events =
            (1 << PY_MONITORING_EVENT_PY_START) | (1 << PY_MONITORING_EVENT_PY_RESUME) |
            (1 << PY_MONITORING_EVENT_PY_RETURN) | (1 << PY_MONITORING_EVENT_PY_YIELD) |
            (1 << PY_MONITORING_EVENT_RAISE) | (1 << PY_MONITORING_EVENT_LINE) |
            (1 << PY_MONITORING_EVENT_JUMP) |
            (1 << PY_MONITORING_EVENT_PY_UNWIND) | (1 << PY_MONITORING_EVENT_PY_THROW) |
            (1 << PY_MONITORING_EVENT_STOP_ITERATION);
    }
    return _PyMonitoring_SetEvents(PY_MONITORING_SYS_TRACE_ID, events);
}

// Enable opcode tracing for the thread's current frame if needed.
static int
maybe_set_opcode_trace(PyThreadState *tstate)
{
    _PyInterpreterFrame *iframe = tstate->current_frame;
    if (iframe == NULL) {
        return 0;
    }
    PyFrameObject *frame = iframe->frame_obj;
    if (frame == NULL || !frame->f_trace_opcodes) {
        return 0;
    }
    return set_opcode_trace_world_stopped(_PyFrame_GetCode(iframe), true);
}

int
_PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
{
    assert(is_tstate_valid(tstate));
    /* The caller must hold a thread state */
    _Py_AssertHoldsTstate();

    /* Call _PySys_Audit() in the context of the current thread state,
       even if tstate is not the current thread state. */
    PyThreadState *current_tstate = _PyThreadState_GET();
    if (_PySys_Audit(current_tstate, "sys.settrace", NULL) < 0) {
        return -1;
    }

    PyInterpreterState *interp = tstate->interp;
    if (_PyOnceFlag_CallOnce(&interp->sys_trace_once_flag,
                             setup_trace_callbacks, NULL) < 0) {
        return -1;
    }

    int err = 0;
    _PyEval_StopTheWorld(interp);
    PyObject *old_traceobj = swap_trace_func_arg(tstate, func, arg);
    err = set_monitoring_trace_events(interp);
    if (err != 0) {
        goto done;
    }
    if (interp->sys_tracing_threads) {
        err = maybe_set_opcode_trace(tstate);
    }
done:
    _PyEval_StartTheWorld(interp);
    Py_XDECREF(old_traceobj);  // needs to be decref'd outside stop-the-world
    return err;
}

int
_PyEval_SetTraceAllThreads(PyInterpreterState *interp, Py_tracefunc func, PyObject *arg)
{
    PyThreadState *current_tstate = _PyThreadState_GET();
    assert(is_tstate_valid(current_tstate));
    assert(current_tstate->interp == interp);

    if (_PySys_Audit(current_tstate, "sys.settrace", NULL) < 0) {
        return -1;
    }

    if (_PyOnceFlag_CallOnce(&interp->sys_trace_once_flag,
                             setup_trace_callbacks, NULL) < 0) {
        return -1;
    }

    PyObject *old_trace_objs = NULL;
    _PyEval_StopTheWorld(interp);
    HEAD_LOCK(&_PyRuntime);
    Py_ssize_t num_thread_states = 0;
    _Py_FOR_EACH_TSTATE_UNLOCKED(interp, p) {
        num_thread_states++;
    }
    old_trace_objs = PyTuple_New(num_thread_states);
    if (old_trace_objs == NULL) {
        HEAD_UNLOCK(&_PyRuntime);
        _PyEval_StartTheWorld(interp);
        return -1;
    }
    _Py_FOR_EACH_TSTATE_UNLOCKED(interp, tstate) {
        PyObject *old = swap_trace_func_arg(tstate, func, arg);
        PyTuple_SET_ITEM(old_trace_objs, --num_thread_states, old);
    }
    if (interp->sys_tracing_threads) {
        _Py_FOR_EACH_TSTATE_UNLOCKED(interp, tstate) {
            int err = maybe_set_opcode_trace(tstate);
            if (err != 0) {
                HEAD_UNLOCK(&_PyRuntime);
                _PyEval_StartTheWorld(interp);
                Py_XDECREF(old_trace_objs);
                return -1;
            }
        }
    }
    HEAD_UNLOCK(&_PyRuntime);
    int err = set_monitoring_trace_events(interp);
    _PyEval_StartTheWorld(interp);
    Py_XDECREF(old_trace_objs);  // needs to be decref'd outside of stop-the-world
    return err;
}
