/* Traceback implementation */#include "Python.h"#include "code.h"#include "frameobject.h"#include "structmember.h"#include "osdefs.h"#include "traceback.h"#define OFF(x) offsetof(PyTracebackObject, x)static struct memberlist tb_memberlist[] = {{"tb_next", T_OBJECT, OFF(tb_next)},{"tb_frame", T_OBJECT, OFF(tb_frame)},{"tb_lasti", T_INT, OFF(tb_lasti)},{"tb_lineno", T_INT, OFF(tb_lineno)},{NULL} /* Sentinel */};static PyObject *tb_getattr(PyTracebackObject *tb, char *name){return PyMember_Get((char *)tb, tb_memberlist, name);}static voidtb_dealloc(PyTracebackObject *tb){PyObject_GC_UnTrack(tb);Py_TRASHCAN_SAFE_BEGIN(tb)Py_XDECREF(tb->tb_next);Py_XDECREF(tb->tb_frame);PyObject_GC_Del(tb);Py_TRASHCAN_SAFE_END(tb)}static inttb_traverse(PyTracebackObject *tb, visitproc visit, void *arg){Py_VISIT(tb->tb_next);Py_VISIT(tb->tb_frame);return 0;}static voidtb_clear(PyTracebackObject *tb){Py_CLEAR(tb->tb_next);Py_CLEAR(tb->tb_frame);}PyTypeObject PyTraceBack_Type = {PyVarObject_HEAD_INIT(&PyType_Type, 0)"traceback",sizeof(PyTracebackObject),0,(destructor)tb_dealloc, /*tp_dealloc*/0, /*tp_print*/(getattrfunc)tb_getattr, /*tp_getattr*/0, /*tp_setattr*/0, /*tp_compare*/0, /*tp_repr*/0, /*tp_as_number*/0, /*tp_as_sequence*/0, /*tp_as_mapping*/0, /* tp_hash */0, /* tp_call */0, /* tp_str */0, /* tp_getattro */0, /* tp_setattro */0, /* tp_as_buffer */Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */0, /* tp_doc */(traverseproc)tb_traverse, /* tp_traverse */(inquiry)tb_clear, /* tp_clear */0, /* tp_richcompare */0, /* tp_weaklistoffset */0, /* tp_iter */0, /* tp_iternext */0, /* tp_methods */0, /* tp_members */0, /* tp_getset */0, /* tp_base */0, /* tp_dict */};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 = PyCode_Addr2Line(frame->f_code,frame->f_lasti);PyObject_GC_Track(tb);}return tb;}intPyTraceBack_Here(PyFrameObject *frame){PyThreadState *tstate = PyThreadState_GET();PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback;PyTracebackObject *tb = newtracebackobject(oldtb, frame);if (tb == NULL)return -1;tstate->curexc_traceback = (PyObject *)tb;Py_XDECREF(oldtb);return 0;}int_Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent){int err = 0;FILE *xfp = NULL;char linebuf[2000];int i;char namebuf[MAXPATHLEN+1];if (filename == NULL)return -1;/* This is needed by Emacs' compile command */#define FMT " File \"%.500s\", line %d, in %.500s\n"xfp = fopen(filename, "r" PY_STDIOTEXTMODE);if (xfp == NULL) {/* Search tail of filename in sys.path before giving up */PyObject *path;const char *tail = strrchr(filename, SEP);if (tail == NULL)tail = filename;elsetail++;path = PySys_GetObject("path");if (path != NULL && PyList_Check(path)) {Py_ssize_t _npath = PyList_Size(path);int npath = Py_SAFE_DOWNCAST(_npath, Py_ssize_t, int);size_t taillen = strlen(tail);for (i = 0; i < npath; i++) {PyObject *v = PyList_GetItem(path, i);if (v == NULL) {PyErr_Clear();break;}if (PyString_Check(v)) {size_t len;len = PyString_GET_SIZE(v);if (len + 1 + taillen >= MAXPATHLEN)continue; /* Too long */strcpy(namebuf, PyString_AsString(v));if (strlen(namebuf) != len)continue; /* v contains '0円' */if (len > 0 && namebuf[len-1] != SEP)namebuf[len++] = SEP;strcpy(namebuf+len, tail);xfp = fopen(namebuf, "r" PY_STDIOTEXTMODE);if (xfp != NULL) {filename = namebuf;break;}}}}}if (xfp == NULL)return err;if (err != 0) {fclose(xfp);return err;}for (i = 0; i < lineno; i++) {char* pLastChar = &linebuf[sizeof(linebuf)-2];do {*pLastChar = '0円';if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, xfp, NULL) == NULL)break;/* fgets read *something*; if it didn't get asfar as pLastChar, it must have found a newlineor hit the end of the file; if pLastChar is \n,it obviously found a newline; else we haven'tyet seen a newline, so must continue */} while (*pLastChar != '0円' && *pLastChar != '\n');}if (i == lineno) {char buf[11];char *p = linebuf;while (*p == ' ' || *p == '\t' || *p == '014円')p++;/* Write some spaces before the line */strcpy(buf, " ");assert (strlen(buf) == 10);while (indent > 0) {if(indent < 10)buf[indent] = '0円';err = PyFile_WriteString(buf, f);if (err != 0)break;indent -= 10;}if (err == 0)err = PyFile_WriteString(p, f);if (err == 0 && strchr(p, '\n') == NULL)err = PyFile_WriteString("\n", f);}fclose(xfp);return err;}static inttb_displayline(PyObject *f, const char *filename, int lineno, const char *name){int err = 0;char linebuf[2000];if (filename == NULL || name == NULL)return -1;/* This is needed by Emacs' compile command */#define FMT " File \"%.500s\", line %d, in %.500s\n"PyOS_snprintf(linebuf, sizeof(linebuf), FMT, filename, lineno, name);err = PyFile_WriteString(linebuf, f);if (err != 0)return err;return _Py_DisplaySourceLine(f, filename, lineno, 4);}static inttb_printinternal(PyTracebackObject *tb, PyObject *f, long limit){int err = 0;long depth = 0;PyTracebackObject *tb1 = tb;while (tb1 != NULL) {depth++;tb1 = tb1->tb_next;}while (tb != NULL && err == 0) {if (depth <= limit) {err = tb_displayline(f,PyString_AsString(tb->tb_frame->f_code->co_filename),tb->tb_lineno,PyString_AsString(tb->tb_frame->f_code->co_name));}depth--;tb = tb->tb_next;if (err == 0)err = PyErr_CheckSignals();}return err;}intPyTraceBack_Print(PyObject *v, PyObject *f){int err;PyObject *limitv;long limit = 1000;if (v == NULL)return 0;if (!PyTraceBack_Check(v)) {PyErr_BadInternalCall();return -1;}limitv = PySys_GetObject("tracebacklimit");if (limitv && PyInt_Check(limitv)) {limit = PyInt_AsLong(limitv);if (limit <= 0)return 0;}err = PyFile_WriteString("Traceback (most recent call last):\n", f);if (!err)err = tb_printinternal((PyTracebackObject *)v, f, limit);return err;}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。