1 2#include "Python.h" 3#include "frameobject.h" 4#include "pycore_code.h" // stats 5#include "pycore_frame.h" 6#include "pycore_object.h" // _PyObject_GC_UNTRACK() 7#include "opcode.h" 8 9int 10_PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg) 11{ 12 Py_VISIT(frame->frame_obj); 13 Py_VISIT(frame->f_locals); 14 Py_VISIT(frame->f_func); 15 Py_VISIT(frame->f_code); 16 /* locals */ 17 PyObject **locals = _PyFrame_GetLocalsArray(frame); 18 int i = 0; 19 /* locals and stack */ 20 for (; i <frame->stacktop; i++) { 21 Py_VISIT(locals[i]); 22 } 23 return 0; 24} 25 26PyFrameObject * 27_PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame) 28{ 29 assert(frame->frame_obj == NULL); 30 PyObject *error_type, *error_value, *error_traceback; 31 PyErr_Fetch(&error_type, &error_value, &error_traceback); 32 33 PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code); 34 if (f == NULL) { 35 Py_XDECREF(error_type); 36 Py_XDECREF(error_value); 37 Py_XDECREF(error_traceback); 38 return NULL; 39 } 40 PyErr_Restore(error_type, error_value, error_traceback); 41 if (frame->frame_obj) { 42 // GH-97002: How did we get into this horrible situation? Most likely, 43 // allocating f triggered a GC collection, which ran some code that 44 // *also* created the same frame... while we were in the middle of 45 // creating it! See test_sneaky_frame_object in test_frame.py for a 46 // concrete example. 47 // 48 // Regardless, just throw f away and use that frame instead, since it's 49 // already been exposed to user code. It's actually a bit tricky to do 50 // this, since we aren't backed by a real _PyInterpreterFrame anymore. 51 // Just pretend that we have an owned, cleared frame so frame_dealloc 52 // doesn't make the situation worse: 53 f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data; 54 f->f_frame->owner = FRAME_CLEARED; 55 f->f_frame->frame_obj = f; 56 Py_DECREF(f); 57 return frame->frame_obj; 58 } 59 assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); 60 assert(frame->owner != FRAME_CLEARED); 61 f->f_frame = frame; 62 frame->frame_obj = f; 63 return f; 64} 65 66void 67_PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest) 68{ 69 assert(src->stacktop >= src->f_code->co_nlocalsplus); 70 Py_ssize_t size = ((char*)&src->localsplus[src->stacktop]) - (char *)src; 71 memcpy(dest, src, size); 72 // Don't leave a dangling pointer to the old frame when creating generators 73 // and coroutines: 74 dest->previous = NULL; 75} 76 77 78static void 79take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) 80{ 81 assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); 82 assert(frame->owner != FRAME_CLEARED); 83 Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame; 84 memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size); 85 frame = (_PyInterpreterFrame *)f->_f_frame_data; 86 f->f_frame = frame; 87 frame->owner = FRAME_OWNED_BY_FRAME_OBJECT; 88 if (_PyFrame_IsIncomplete(frame)) { 89 // This may be a newly-created generator or coroutine frame. Since it's 90 // dead anyways, just pretend that the first RESUME ran: 91 PyCodeObject *code = frame->f_code; 92 frame->prev_instr = _PyCode_CODE(code) + code->_co_firsttraceable; 93 } 94 assert(!_PyFrame_IsIncomplete(frame)); 95 assert(f->f_back == NULL); 96 _PyInterpreterFrame *prev = frame->previous; 97 while (prev && _PyFrame_IsIncomplete(prev)) { 98 prev = prev->previous; 99 } 100 if (prev) { 101 /* Link PyFrameObjects.f_back and remove link through _PyInterpreterFrame.previous */ 102 PyFrameObject *back = _PyFrame_GetFrameObject(prev); 103 if (back == NULL) { 104 /* Memory error here. */ 105 assert(PyErr_ExceptionMatches(PyExc_MemoryError)); 106 /* Nothing we can do about it */ 107 PyErr_Clear(); 108 } 109 else { 110 f->f_back = (PyFrameObject *)Py_NewRef(back); 111 } 112 frame->previous = NULL; 113 } 114 if (!_PyObject_GC_IS_TRACKED((PyObject *)f)) { 115 _PyObject_GC_TRACK((PyObject *)f); 116 } 117} 118 119void 120_PyFrame_Clear(_PyInterpreterFrame *frame) 121{ 122 /* It is the responsibility of the owning generator/coroutine 123 * to have cleared the enclosing generator, if any. */ 124 assert(frame->owner != FRAME_OWNED_BY_GENERATOR || 125 _PyFrame_GetGenerator(frame)->gi_frame_state == FRAME_CLEARED); 126 // GH-99729: Clearing this frame can expose the stack (via finalizers). It's 127 // crucial that this frame has been unlinked, and is no longer visible: 128 assert(_PyThreadState_GET()->cframe->current_frame != frame); 129 if (frame->frame_obj) { 130 PyFrameObject *f = frame->frame_obj; 131 frame->frame_obj = NULL; 132 if (Py_REFCNT(f) > 1) { 133 take_ownership(f, frame); 134 Py_DECREF(f); 135 return; 136 } 137 Py_DECREF(f); 138 } 139 assert(frame->stacktop >= 0); 140 for (int i = 0; i < frame->stacktop; i++) { 141 Py_XDECREF(frame->localsplus[i]); 142 } 143 Py_XDECREF(frame->frame_obj); 144 Py_XDECREF(frame->f_locals); 145 Py_DECREF(frame->f_func); 146 Py_DECREF(frame->f_code); 147} 148 149/* Consumes reference to func */ 150_PyInterpreterFrame * 151_PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func) 152{ 153 PyCodeObject *code = (PyCodeObject *)func->func_code; 154 size_t size = code->co_nlocalsplus + code->co_stacksize + FRAME_SPECIALS_SIZE; 155 CALL_STAT_INC(frames_pushed); 156 _PyInterpreterFrame *new_frame = _PyThreadState_BumpFramePointer(tstate, size); 157 if (new_frame == NULL) { 158 Py_DECREF(func); 159 return NULL; 160 } 161 _PyFrame_InitializeSpecials(new_frame, func, NULL, code->co_nlocalsplus); 162 return new_frame; 163} 164 165int 166_PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame) 167{ 168 int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT); 169 return PyCode_Addr2Line(frame->f_code, addr); 170} 171