/ 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_