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