/* 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, to);
    int from_line = _Py_Instrumentation_GetLine(code, 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;
}
