static void dump_traceback(int fd, PyThreadState *tstate, int write_header) { PyFrameObject *frame; unsigned int depth; if (write_header) PUTS(fd, "Stack (most recent call first):\n"); frame = _PyThreadState_GetFrame(tstate); if (frame == NULL) return; depth = 0; while (frame != NULL) { if (MAX_FRAME_DEPTH <= depth) { PUTS(fd, " ...\n"); break; } if (!PyFrame_Check(frame)) break; dump_frame(fd, frame); frame = frame->f_back; depth++; } }
PyObject * PyTasklet_GetFrame(PyTaskletObject *task) { PyFrameObject *f = (PyFrameObject *) slp_get_frame(task); while (f != NULL && !PyFrame_Check(f)) { f = f->f_back; } Py_XINCREF(f); return (PyObject *) f; }
static PyObject* genbuild(PyObject* g) { PyObject* x; PyFrameObject* f; PyCodeObject* co; PyObject** dummy; int i, res; x = PyObject_GetAttrString(g, "gi_running"); if (x == NULL) return NULL; res = PyObject_IsTrue(x); if (res < 0) return NULL; if (res) { PyErr_SetString(PyExc_ValueError, "generator is running"); return NULL; } x = PyObject_GetAttrString(g, "gi_frame"); if (x == NULL) return NULL; if (!PyFrame_Check(x)) { PyErr_SetString(PyExc_TypeError, "g.gi_frame must be a frame object"); return NULL; } f = (PyFrameObject*) x; co = f->f_code; if (!(co->co_flags & CO_GENERATOR)) { PyErr_SetString(PyExc_ValueError, "the frame is not from a generator"); return NULL; } if (f->f_stacktop == NULL) { Py_INCREF(g); /* exhausted -- can return 'g' itself */ return g; } if (f->f_nfreevars || f->f_ncells) { PyErr_SetString(PyExc_ValueError, "generator has cell or free vars"); return NULL; } dummy = (PyObject**) malloc(co->co_argcount * sizeof(PyObject*)); if (dummy == NULL) return PyErr_NoMemory(); for (i=0; i<co->co_argcount; i++) dummy[i] = Py_None; x = PyEval_EvalCodeEx(co, f->f_globals, f->f_locals, dummy, co->co_argcount, NULL, 0, NULL, 0, NULL); free(dummy); return x; }
static PyObject * frame_getback(PyFrameObject *f, void *nope) { PyFrameObject *fb = f->f_back; PyObject *ret; while (fb != NULL && ! PyFrame_Check(fb)) fb = fb->f_back; ret = (PyObject *) fb; if (ret == NULL) ret = Py_None; Py_INCREF(ret); return ret; }
/* Default implementation for _PyThreadState_GetFrame */ static struct _frame * threadstate_getframe(PyThreadState *self) { #ifdef STACKLESS /* make sure to return a real frame */ struct _frame *f = self->frame; while (f != NULL && !PyFrame_Check(f)) f = f->f_back; return f; #else return self->frame; #endif }
PyObject * is_frame_utf8(PyObject* self, PyObject* args) { PyFrameObject *frame = PyEval_GetFrame(); while (frame != NULL) { if (!(PyFrame_Check(frame) && is_utf8(frame->f_code->co_filename) && is_utf8(frame->f_code->co_name))) { Py_RETURN_FALSE; } frame = frame->f_back; } Py_RETURN_TRUE; }
static PyTracebackObject * newtracebackobject(PyTracebackObject *next, PyFrameObject *frame) { PyTracebackObject *tb; if ((next != NULL && !PyTraceBack_Check(next)) || frame == NULL || !PyFrame_Check(frame)) { PyErr_BadInternalCall(); return NULL; } tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type); if (tb != NULL) { Py_XINCREF(next); tb->tb_next = next; Py_XINCREF(frame); tb->tb_frame = frame; tb->tb_lasti = frame->f_lasti; tb->tb_lineno = PyFrame_GetLineNumber(frame); PyObject_GC_Track(tb); } return tb; }
static size_t __interpreter_traceback(PyFrameObject *frame, struct frame *tsf, int max) { size_t depth = 0; while (frame != NULL && depth < max) { if (!(PyFrame_Check(frame) && frame->f_code != NULL && PyCode_Check(frame->f_code) && frame->f_code->co_filename != NULL && PyUnicode_Check(frame->f_code->co_filename) && frame->f_code->co_name != NULL && PyUnicode_Check(frame->f_code->co_name))) { break; } struct frame *item = &tsf[depth]; memset(item, 0, sizeof(*item)); populate_utf8(frame->f_code->co_filename, &item->co_filename, &item->co_filename_len); populate_utf8(frame->f_code->co_name, &item->co_name, &item->co_name_len); item->lineno = PyFrame_GetLineNumber(frame); frame = frame->f_back; depth++; } return depth; }
static PyObject* adb_setLocal(PyObject* unused, PyObject* args) { PyFrameObject* frame = NULL; PyObject* value = NULL; char *name; int i; if (!PyArg_ParseTuple(args, "OsO:setlocal", &frame, &name, &value)) { return NULL; } if (!PyFrame_Check(frame)) { return NULL; } for(i=0; i < PySequence_Length(frame->f_locals); ++i) { if ( strcmp(GETITEMNAME(frame->f_code->co_varnames,i),name) == 0 ) { Py_XDECREF(frame->f_localsplus[i]); Py_INCREF(value); frame->f_localsplus[i] = value; } } Py_INCREF(Py_None); return Py_None; }
static PyObject * tb_create_raw(PyTracebackObject *next, PyFrameObject *frame, int lasti, int lineno) { PyTracebackObject *tb; if ((next != NULL && !PyTraceBack_Check(next)) || frame == NULL || !PyFrame_Check(frame)) { PyErr_BadInternalCall(); return NULL; } tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type); if (tb != NULL) { Py_XINCREF(next); tb->tb_next = next; Py_XINCREF(frame); tb->tb_frame = frame; tb->tb_lasti = lasti; tb->tb_lineno = lineno; PyObject_GC_Track(tb); } return (PyObject *)tb; }
void _PyTrash_deposit_object(PyObject *op) { int typecode; if (PyTuple_Check(op)) typecode = Py_TRASHCAN_TUPLE; else if (PyList_Check(op)) typecode = Py_TRASHCAN_LIST; else if (PyDict_Check(op)) typecode = Py_TRASHCAN_DICT; else if (PyFrame_Check(op)) typecode = Py_TRASHCAN_FRAME; else if (PyTraceBack_Check(op)) typecode = Py_TRASHCAN_TRACEBACK; else /* We have a bug here -- those are the only types in GC */ { Py_FatalError("Type not supported in GC -- internal bug"); return; /* pacify compiler -- execution never here */ } op->ob_refcnt = typecode; op->ob_type = (PyTypeObject*)_PyTrash_delete_later; _PyTrash_delete_later = op; }
static PyObject * tasklet_setstate(PyObject *self, PyObject *args) { PyTaskletObject *t = (PyTaskletObject *) self; PyObject *tempval, *lis; int flags, nesting_level; PyFrameObject *f; Py_ssize_t i, nframes; int j; if (!PyArg_ParseTuple(args, "iOiO!:tasklet", &flags, &tempval, &nesting_level, &PyList_Type, &lis)) return NULL; nframes = PyList_GET_SIZE(lis); TASKLET_SETVAL(t, tempval); /* There is a unpickling race condition. While it is rare, * sometimes tasklets get their setstate call after the * channel they are blocked on. If this happens and we * do not account for it, they will be left in a broken * state where they are on the channels chain, but have * cleared their blocked flag. * * We will assume that the presence of a chain, can only * mean that the chain is that of a channel, rather than * that of the main tasklet/scheduler. And therefore * they can leave their blocked flag in place because the * channel would have set it. */ j = t->flags.blocked; *(int *)&t->flags = flags; if (t->next == NULL) { t->flags.blocked = 0; } else { t->flags.blocked = j; } /* t->nesting_level = nesting_level; XXX how do we handle this? XXX to be done: pickle the cstate without a ref to the task. XXX This should make it not runnable in the future. */ if (nframes > 0) { PyFrameObject *back; f = (PyFrameObject *) PyList_GET_ITEM(lis, 0); if ((f = slp_ensure_new_frame(f)) == NULL) return NULL; back = f; for (i=1; i<nframes; ++i) { f = (PyFrameObject *) PyList_GET_ITEM(lis, i); if ((f = slp_ensure_new_frame(f)) == NULL) return NULL; Py_INCREF(back); f->f_back = back; back = f; } t->f.frame = f; } /* walk frames again and calculate recursion_depth */ for (f = t->f.frame; f != NULL; f = f->f_back) { if (PyFrame_Check(f) && f->f_execute != PyEval_EvalFrameEx_slp) { /* * we count running frames which *have* added * to recursion_depth */ ++t->recursion_depth; } } Py_INCREF(self); return self; }
static PyObject * ntracenative_frameSetLocals(PyObject *self, PyObject *args) { PyObject *frameobj = NULL,*dict = NULL; PyFrameObject *frame; (void) self; //printf("before parse\n"); if (!PyArg_ParseTuple( args, "OO", &frameobj, &dict)) { return NULL; } //printf("before framecheck frameobj=%p dict=%p\n", frameobj, dict); if ( frameobj == NULL || !PyFrame_Check(frameobj) ) // check if frame tame { return NULL; } //printf("before dictcheck dict=%p\n", dict); if ( !PyDict_Check(dict) ) { return NULL; } //printf("allchecks ok\n"); frame = (PyFrameObject *) frameobj; if (PyDict_CheckExact(frame->f_locals)) { PyObject *oldLocals; //printf("set f_locals\n"); PyDict_Merge(dict, frame->f_locals, 1); // 1 - add reference to keys and values Py_INCREF(dict); oldLocals = frame->f_locals; frame->f_locals = dict; if (oldLocals != NULL) Py_DECREF( oldLocals ); } #if 0 if (PyDict_CheckExact(frame->f_globals)) { PyObject *oldLocals; PyDict_Merge(dict, frame->f_globals, 1); // 1 - add reference to keys and values Py_INCREF(dict); oldLocals = frame->f_globals; frame->f_globals = dict; if (oldLocals != NULL) Py_DECREF( oldLocals ); } #endif return Py_BuildValue("i", 0); }
static int gencopy(PyObject* g2, PyObject* g) { PyObject* x; PyFrameObject* f; PyFrameObject* f2; PyCodeObject* co; int i, res; if (g != g2) { if (g2->ob_type != g->ob_type) { PyErr_SetString(PyExc_TypeError, "type mismatch"); return -1; } x = PyObject_GetAttrString(g, "gi_frame"); if (x == NULL) return -1; if (!PyFrame_Check(x)) { PyErr_SetString(PyExc_TypeError, "g.gi_frame must be a frame object"); return -1; } f = (PyFrameObject*) x; co = f->f_code; x = PyObject_GetAttrString(g2, "gi_frame"); if (x == NULL) return -1; if (!PyFrame_Check(x)) { PyErr_SetString(PyExc_TypeError, "returned gi_frame"); return -1; } f2 = (PyFrameObject*) x; if (f2->f_stacksize != f->f_stacksize) { PyErr_SetString(PyExc_TypeError, "stack size mismatch"); return -1; } if (f2->f_stacktop != NULL) while (f2->f_stacktop != f2->f_localsplus) { f2->f_stacktop--; Py_XDECREF(*f2->f_stacktop); } res = f->f_stacktop - f->f_localsplus; f2->f_lasti = f->f_lasti; f2->f_iblock = f->f_iblock; memcpy(f2->f_blockstack, f->f_blockstack, sizeof(PyTryBlock)*f->f_iblock); f2->f_stacktop = f2->f_localsplus; for (i=0; i<res; i++) { x = f->f_localsplus[i]; if (x != NULL) x = copyrec(x); *f2->f_stacktop++ = x; } } return 0; }
PyFrameObject * PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, PyObject *locals) { PyFrameObject *back = tstate->frame; static PyObject *builtin_object; PyFrameObject *f; PyObject *builtins; int extras; if (builtin_object == NULL) { builtin_object = PyString_InternFromString("__builtins__"); if (builtin_object == NULL) return NULL; } if ((back != NULL && !PyFrame_Check(back)) || code == NULL || !PyCode_Check(code) || globals == NULL || !PyDict_Check(globals) || (locals != NULL && !PyDict_Check(locals))) { PyErr_BadInternalCall(); return NULL; } extras = code->co_stacksize + code->co_nlocals; if (back == NULL || back->f_globals != globals) { builtins = PyDict_GetItem(globals, builtin_object); if (builtins != NULL && PyModule_Check(builtins)) builtins = PyModule_GetDict(builtins); } else { /* If we share the globals, we share the builtins. Save a lookup and a call. */ builtins = back->f_builtins; } if (builtins != NULL && !PyDict_Check(builtins)) builtins = NULL; if (free_list == NULL) { /* PyObject_New is inlined */ f = (PyFrameObject *) PyObject_MALLOC(sizeof(PyFrameObject) + extras*sizeof(PyObject *)); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); PyObject_INIT(f, &PyFrame_Type); } else { f = free_list; free_list = free_list->f_back; if (f->f_nlocals + f->f_stacksize < extras) { f = (PyFrameObject *) PyObject_REALLOC(f, sizeof(PyFrameObject) + extras*sizeof(PyObject *)); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); } else extras = f->f_nlocals + f->f_stacksize; PyObject_INIT(f, &PyFrame_Type); } if (builtins == NULL) { /* No builtins! Make up a minimal one. */ builtins = PyDict_New(); if (builtins == NULL || /* Give them 'None', at least. */ PyDict_SetItemString(builtins, "None", Py_None) < 0) { Py_DECREF(f); return NULL; } } else Py_XINCREF(builtins); f->f_builtins = builtins; Py_XINCREF(back); f->f_back = back; Py_INCREF(code); f->f_code = code; Py_INCREF(globals); f->f_globals = globals; if (code->co_flags & CO_NEWLOCALS) { if (code->co_flags & CO_OPTIMIZED) locals = NULL; /* Let fast_2_locals handle it */ else { locals = PyDict_New(); if (locals == NULL) { Py_DECREF(f); return NULL; } } } else { if (locals == NULL) locals = globals; Py_INCREF(locals); } f->f_locals = locals; f->f_trace = NULL; f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL; f->f_tstate = tstate; f->f_lasti = 0; f->f_lineno = code->co_firstlineno; f->f_restricted = (builtins != tstate->interp->builtins); f->f_iblock = 0; f->f_nlocals = code->co_nlocals; f->f_stacksize = extras - code->co_nlocals; while (--extras >= 0) f->f_localsplus[extras] = NULL; f->f_valuestack = f->f_localsplus + f->f_nlocals; return f; }
static int rootstate_relate(NyHeapRelate *r) { NyHeapViewObject *hv = (void *)r->hv; PyThreadState *ts, *bts = PyThreadState_GET(); PyInterpreterState *is; int isframe = PyFrame_Check(r->tgt); int isno; for (is = PyInterpreterState_Head(), isno = 0; is; is = PyInterpreterState_Next(is), isno++) ; for (is = PyInterpreterState_Head(), isno--; is; is = PyInterpreterState_Next(is), isno--) { char buf[100]; ISATTR(modules); ISATTR(sysdict); ISATTR(builtins); #if PY_VERSION_HEX >= 0x020303f0 ISATTR(codec_search_path); ISATTR(codec_search_cache); ISATTR(codec_error_registry); #endif for (ts = is->tstate_head; ts; ts = ts->next) { if ((ts == bts && r->tgt == hv->limitframe) || (!hv->limitframe && isframe)) { int frameno = -1; int numframes = 0; PyFrameObject *frame; for (frame = (PyFrameObject *)ts->frame; frame; frame = frame->f_back) { numframes ++; if (r->tgt == (PyObject *)frame) frameno = numframes; } if (frameno != -1) { frameno = numframes - frameno; sprintf(buf,"t%lu_f%d", THREAD_ID(ts), frameno); if (r->visit(NYHR_ATTRIBUTE, PyString_FromString(buf), r)) return 1; } } TSATTR(ts, c_profileobj); TSATTR(ts, c_traceobj); TSATTR(ts, curexc_type); TSATTR(ts, curexc_value); TSATTR(ts, curexc_traceback); TSATTR(ts, exc_type); TSATTR(ts, exc_value); TSATTR(ts, exc_traceback); TSATTR(ts, dict); #if PY_VERSION_HEX >= 0x020303f0 TSATTR(ts, async_exc); #endif } } return 0; }