/ lib / debugpy / _vendored / pydevd / pydevd_attach_to_process / common / py_custom_pyeval_settrace_311.hpp
py_custom_pyeval_settrace_311.hpp
  1  #ifndef _PY_CUSTOM_PYEVAL_SETTRACE_311_HPP_
  2  #define _PY_CUSTOM_PYEVAL_SETTRACE_311_HPP_
  3  
  4  #include "python.h"
  5  #include "py_utils.hpp"
  6  
  7  static PyObject *
  8  InternalCallTrampoline311(PyObject* callback,
  9                  PyFrameObject311 *frame, int what, PyObject *arg)
 10  {
 11      PyObject *result;
 12      PyObject *stack[3];
 13  
 14  // Note: this is commented out from CPython (we shouldn't need it and it adds a reasonable overhead).
 15  //     if (PyFrame_FastToLocalsWithError(frame) < 0) {
 16  //         return NULL;
 17  //     }
 18  //
 19      stack[0] = (PyObject *)frame;
 20      stack[1] = InternalWhatstrings_37[what];
 21      stack[2] = (arg != NULL) ? arg : internalInitializeCustomPyEvalSetTrace->pyNone;
 22      
 23      
 24      // Helper to print info.
 25      //printf("--- start\n");
 26      //printf("%s\n", internalInitializeCustomPyEvalSetTrace->pyUnicode_AsUTF8(internalInitializeCustomPyEvalSetTrace->pyObject_Repr((PyObject *)stack[0])));
 27      //printf("%s\n", internalInitializeCustomPyEvalSetTrace->pyUnicode_AsUTF8(internalInitializeCustomPyEvalSetTrace->pyObject_Repr((PyObject *)stack[1])));
 28      //printf("%s\n", internalInitializeCustomPyEvalSetTrace->pyUnicode_AsUTF8(internalInitializeCustomPyEvalSetTrace->pyObject_Repr((PyObject *)stack[2])));
 29      //printf("--- end\n");
 30  
 31      result = internalInitializeCustomPyEvalSetTrace->pyObject_FastCallDict(callback, stack, 3, NULL);
 32  
 33  // Note: this is commented out from CPython (we shouldn't need it and it adds a reasonable overhead).
 34  //     PyFrame_LocalsToFast(frame, 1);
 35  
 36      if (result == NULL) {
 37          internalInitializeCustomPyEvalSetTrace->pyTraceBack_Here(frame);
 38      }
 39  
 40      return result;
 41  }
 42  
 43  // See: static int trace_trampoline(PyObject *self, PyFrameObject *frame, int what, PyObject *arg)
 44  // in: https://github.com/python/cpython/blob/3.11/Python/sysmodule.c
 45  static int
 46  InternalTraceTrampoline311(PyObject *self, PyFrameObject *frameParam,
 47                   int what, PyObject *arg)
 48  {
 49      PyObject *callback;
 50      PyObject *result;
 51      
 52      PyFrameObject311 *frame = reinterpret_cast<PyFrameObject311*>(frameParam);
 53  
 54      if (what == PyTrace_CALL){
 55          callback = self;
 56      } else {
 57          callback = frame->f_trace;
 58      }
 59  
 60      if (callback == NULL){
 61          return 0;
 62      }
 63  
 64      result = InternalCallTrampoline311(callback, frame, what, arg);
 65      if (result == NULL) {
 66          // Note: calling the original sys.settrace here.
 67          internalInitializeCustomPyEvalSetTrace->pyEval_SetTrace(NULL, NULL);
 68          PyObject *temp_f_trace = frame->f_trace;
 69          frame->f_trace = NULL;
 70          if(temp_f_trace != NULL){
 71              DecRef(temp_f_trace, internalInitializeCustomPyEvalSetTrace->isDebug);
 72          }
 73          return -1;
 74      }
 75      if (result != internalInitializeCustomPyEvalSetTrace->pyNone) {
 76          PyObject *tmp = frame->f_trace;
 77          frame->f_trace = result;
 78          DecRef(tmp, internalInitializeCustomPyEvalSetTrace->isDebug);
 79      }
 80      else {
 81          DecRef(result, internalInitializeCustomPyEvalSetTrace->isDebug);
 82      }
 83      return 0;
 84  }
 85  
 86  // Based on ceval.c (PyEval_SetTrace(Py_tracefunc func, PyObject *arg))
 87  // https://github.com/python/cpython/blob/3.11/Python/ceval.c
 88  template<typename T>
 89  void InternalPySetTrace_Template311(T tstate, PyObjectHolder* traceFunc, bool isDebug)
 90  {
 91      PyObject *traceobj = tstate->c_traceobj;
 92  
 93      PyObject *arg = traceFunc->ToPython();
 94      IncRef(arg);
 95      tstate->c_tracefunc = NULL;
 96      tstate->c_traceobj = NULL;
 97      
 98      // This is different (previously it was just: tstate->use_tracing, now
 99      // this flag is per-frame). 
100      int use_tracing = (tstate->c_profilefunc != NULL);
101                             
102      // Note: before 3.11 this was just 1 or 0, now it needs to be 255 or 0.
103      tstate->cframe->use_tracing = (use_tracing ? 255 : 0);
104      
105      if(traceobj != NULL){
106          DecRef(traceobj, isDebug);
107      }
108      tstate->c_tracefunc = InternalTraceTrampoline311;
109      tstate->c_traceobj = arg;
110      /* Flag that tracing or profiling is turned on */
111      use_tracing = ((InternalTraceTrampoline311 != NULL)
112                             || (tstate->c_profilefunc != NULL));
113                             
114      // Note: before 3.11 this was just 1 or 0, now it needs to be 255 or 0.
115      tstate->cframe->use_tracing = (use_tracing ? 255 : 0);
116  
117  };
118  
119  
120  #endif //_PY_CUSTOM_PYEVAL_SETTRACE_311_HPP_