int uwsgi_python_profiler_call(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) { #ifndef UWSGI_PYPY static uint64_t last_ts = 0; uint64_t now = uwsgi_micros(); uint64_t delta = 0; switch(what) { case PyTrace_CALL: if (last_ts == 0) delta = 0; else delta = now - last_ts; last_ts = now; uwsgi_log("[uWSGI Python profiler %llu] CALL: %s (line %d) -> %s %d args, stacksize %d\n", (unsigned long long) delta, PyString_AsString(frame->f_code->co_filename), PyFrame_GetLineNumber(frame), PyString_AsString(frame->f_code->co_name), frame->f_code->co_argcount, frame->f_code->co_stacksize); break; case PyTrace_C_CALL: if (last_ts == 0) delta = 0; else delta = now - last_ts; last_ts = now; uwsgi_log("[uWSGI Python profiler %llu] C CALL: %s (line %d) -> %s %d args, stacksize %d\n", (unsigned long long) delta, PyString_AsString(frame->f_code->co_filename), PyFrame_GetLineNumber(frame), PyEval_GetFuncName(arg), frame->f_code->co_argcount, frame->f_code->co_stacksize); break; } #endif return 0; }
static void pybacktrace(unw_cursor_t cursor) { unw_word_t bp; PyFrameObject *frame; PyObject *fileobj, *funcobj; int depth = 0; unw_get_reg(&cursor, UNW_X86_64_RBP, &bp); frame = (PyFrameObject*)bp; while (frame && (depth < MAX_STACK_DEPTH)) { fileobj = PyUnicode_AsUTF8String(frame->f_code->co_filename); funcobj = PyUnicode_AsUTF8String(frame->f_code->co_name); printf("%s(%d): %s\n", fileobj?PyBytes_AsString(fileobj):"???", PyFrame_GetLineNumber(frame), funcobj?PyBytes_AsString(funcobj):"???"); if (fileobj) Py_DECREF(fileobj); if (funcobj) Py_DECREF(funcobj); frame = frame->f_back; depth++; } }
static PyObject * frame_repr(PyFrameObject *f) { int lineno = PyFrame_GetLineNumber(f); return PyUnicode_FromFormat( "<frame at %p, file %R, line %d, code %S>", f, f->f_code->co_filename, lineno, f->f_code->co_name); }
int uwsgi_python_profiler_call(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) { #ifndef UWSGI_PYPY switch(what) { case PyTrace_CALL: uwsgi_log("[uWSGI Python profiler] CALL: %s (line %d) -> %s %d args, stacksize %d\n", PyString_AsString(frame->f_code->co_filename), PyFrame_GetLineNumber(frame), PyString_AsString(frame->f_code->co_name), frame->f_code->co_argcount, frame->f_code->co_stacksize); break; case PyTrace_C_CALL: uwsgi_log("[uWSGI Python profiler] C CALL: %s (line %d) -> %s %d args, stacksize %d\n", PyString_AsString(frame->f_code->co_filename), PyFrame_GetLineNumber(frame), PyEval_GetFuncName(arg), frame->f_code->co_argcount, frame->f_code->co_stacksize); break; } #endif return 0; }
static int frame_settrace(PyFrameObject *f, PyObject* v, void *closure) { /* We rely on f_lineno being accurate when f_trace is set. */ f->f_lineno = PyFrame_GetLineNumber(f); if (v == Py_None) v = NULL; Py_XINCREF(v); Py_XSETREF(f->f_trace, v); return 0; }
int PyTraceBack_Here(PyFrameObject *frame) { PyObject *exc, *val, *tb, *newtb; PyErr_Fetch(&exc, &val, &tb); newtb = tb_create_raw((PyTracebackObject *)tb, frame, frame->f_lasti, PyFrame_GetLineNumber(frame)); if (newtb == NULL) { _PyErr_ChainExceptions(exc, val, tb); return -1; } PyErr_Restore(exc, val, newtb); Py_XDECREF(tb); return 0; }
static int frame_settrace(PyFrameObject *f, PyObject* v, void *closure) { PyObject* old_value; /* We rely on f_lineno being accurate when f_trace is set. */ f->f_lineno = PyFrame_GetLineNumber(f); old_value = f->f_trace; Py_XINCREF(v); f->f_trace = v; Py_XDECREF(old_value); return 0; }
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; }
void PyC_FileAndNum(const char **filename, int *lineno) { PyFrameObject *frame; if (filename) *filename= NULL; if (lineno) *lineno = -1; if (!(frame= PyThreadState_GET()->frame)) { return; } /* when executing a script */ if (filename) { *filename = _PyUnicode_AsString(frame->f_code->co_filename); } /* when executing a module */ if(filename && *filename == NULL) { /* try an alternative method to get the filename - module based * references below are all borrowed (double checked) */ PyObject *mod_name= PyDict_GetItemString(PyEval_GetGlobals(), "__name__"); if(mod_name) { PyObject *mod= PyDict_GetItem(PyImport_GetModuleDict(), mod_name); if(mod) { *filename= PyModule_GetFilename(mod); } /* unlikely, fallback */ if(*filename == NULL) { *filename= _PyUnicode_AsString(mod_name); } } } if (lineno) { *lineno = PyFrame_GetLineNumber(frame); } }
int PythonContext::traceEvent(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) { PyObject *thisobj = PyDict_GetItemString(obj, "thisobj"); uint64_t thisuint64 = PyLong_AsUnsignedLongLong(thisobj); uintptr_t thisint = (uintptr_t)thisuint64; PythonContext *context = (PythonContext *)thisint; PyObject *compiled = PyDict_GetItemString(obj, "compiled"); if(compiled == (PyObject *)frame->f_code && what == PyTrace_LINE) { context->location.line = PyFrame_GetLineNumber(frame); emit context->traceLine(context->location.file, context->location.line); } if(context->shouldAbort()) { PyErr_SetString(PyExc_SystemExit, "Execution aborted."); return -1; } return 0; }
/* Returns 0 on error (no new refs), 1 on success */ static int setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, PyObject **module, PyObject **registry) { PyObject *globals; /* Setup globals and lineno. */ PyFrameObject *f = PyThreadState_GET()->frame; // Stack level comparisons to Python code is off by one as there is no // warnings-related stack level to avoid. if (stack_level <= 0 || is_internal_frame(f)) { while (--stack_level > 0 && f != NULL) { f = f->f_back; } } else { while (--stack_level > 0 && f != NULL) { f = next_external_frame(f); } } if (f == NULL) { globals = PyThreadState_Get()->interp->sysdict; *lineno = 1; } else { globals = f->f_globals; *lineno = PyFrame_GetLineNumber(f); } *module = NULL; /* Setup registry. */ assert(globals != NULL); assert(PyDict_Check(globals)); *registry = PyDict_GetItemString(globals, "__warningregistry__"); if (*registry == NULL) { int rc; *registry = PyDict_New(); if (*registry == NULL) return 0; rc = PyDict_SetItemString(globals, "__warningregistry__", *registry); if (rc < 0) goto handle_error; } else Py_INCREF(*registry); /* Setup module. */ *module = PyDict_GetItemString(globals, "__name__"); if (*module == NULL) { *module = PyUnicode_FromString("<string>"); if (*module == NULL) goto handle_error; } else Py_INCREF(*module); /* Setup filename. */ *filename = PyDict_GetItemString(globals, "__file__"); if (*filename != NULL && PyUnicode_Check(*filename)) { Py_ssize_t len; int kind; void *data; if (PyUnicode_READY(*filename)) goto handle_error; len = PyUnicode_GetLength(*filename); kind = PyUnicode_KIND(*filename); data = PyUnicode_DATA(*filename); #define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0) /* if filename.lower().endswith(".pyc"): */ if (len >= 4 && PyUnicode_READ(kind, data, len-4) == '.' && ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' && ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' && ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c') { *filename = PyUnicode_Substring(*filename, 0, PyUnicode_GET_LENGTH(*filename)-1); if (*filename == NULL) goto handle_error; } else Py_INCREF(*filename); } else { *filename = NULL; if (*module != Py_None && PyUnicode_CompareWithASCIIString(*module, "__main__") == 0) { PyObject *argv = _PySys_GetObjectId(&PyId_argv); /* PyList_Check() is needed because sys.argv is set to None during Python finalization */ if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) { int is_true; *filename = PyList_GetItem(argv, 0); Py_INCREF(*filename); /* If sys.argv[0] is false, then use '__main__'. */ is_true = PyObject_IsTrue(*filename); if (is_true < 0) { Py_DECREF(*filename); goto handle_error; } else if (!is_true) { Py_XSETREF(*filename, PyUnicode_FromString("__main__")); if (*filename == NULL) goto handle_error; } } else { /* embedded interpreters don't have sys.argv, see bug #839151 */ *filename = PyUnicode_FromString("__main__"); if (*filename == NULL) goto handle_error; } } if (*filename == NULL) { *filename = *module; Py_INCREF(*filename); } } return 1; handle_error: /* filename not XDECREF'ed here as there is no way to jump here with a dangling reference. */ Py_XDECREF(*registry); Py_XDECREF(*module); return 0; }
/* Returns 0 on error (no new refs), 1 on success */ static int setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, PyObject **module, PyObject **registry) { PyObject *globals; /* Setup globals and lineno. */ PyFrameObject *f = PyThreadState_GET()->frame; while (--stack_level > 0 && f != NULL) f = f->f_back; if (f == NULL) { globals = PyThreadState_Get()->interp->sysdict; *lineno = 1; } else { globals = f->f_globals; *lineno = PyFrame_GetLineNumber(f); } *module = NULL; /* Setup registry. */ assert(globals != NULL); assert(PyDict_Check(globals)); *registry = PyDict_GetItemString(globals, "__warningregistry__"); if (*registry == NULL) { int rc; *registry = PyDict_New(); if (*registry == NULL) return 0; rc = PyDict_SetItemString(globals, "__warningregistry__", *registry); if (rc < 0) goto handle_error; } else Py_INCREF(*registry); /* Setup module. */ *module = PyDict_GetItemString(globals, "__name__"); if (*module == NULL) { *module = PyString_FromString("<string>"); if (*module == NULL) goto handle_error; } else Py_INCREF(*module); /* Setup filename. */ *filename = PyDict_GetItemString(globals, "__file__"); if (*filename != NULL) { Py_ssize_t len = PyString_Size(*filename); const char *file_str = PyString_AsString(*filename); if (file_str == NULL || (len < 0 && PyErr_Occurred())) goto handle_error; /* if filename.lower().endswith((".pyc", ".pyo")): */ if (len >= 4 && file_str[len-4] == '.' && tolower(file_str[len-3]) == 'p' && tolower(file_str[len-2]) == 'y' && (tolower(file_str[len-1]) == 'c' || tolower(file_str[len-1]) == 'o')) { *filename = PyString_FromStringAndSize(file_str, len-1); if (*filename == NULL) goto handle_error; } else Py_INCREF(*filename); } else { const char *module_str = PyString_AsString(*module); if (module_str && strcmp(module_str, "__main__") == 0) { PyObject *argv = PySys_GetObject("argv"); if (argv != NULL && PyList_Size(argv) > 0) { int is_true; *filename = PyList_GetItem(argv, 0); Py_INCREF(*filename); /* If sys.argv[0] is false, then use '__main__'. */ is_true = PyObject_IsTrue(*filename); if (is_true < 0) { Py_DECREF(*filename); goto handle_error; } else if (!is_true) { Py_DECREF(*filename); *filename = PyString_FromString("__main__"); if (*filename == NULL) goto handle_error; } } else { /* embedded interpreters don't have sys.argv, see bug #839151 */ *filename = PyString_FromString("__main__"); if (*filename == NULL) goto handle_error; } } if (*filename == NULL) { *filename = *module; Py_INCREF(*filename); } } return 1; handle_error: /* filename not XDECREF'ed here as there is no way to jump here with a dangling reference. */ Py_XDECREF(*registry); Py_XDECREF(*module); return 0; }
static PyObject * frame_getlineno(PyFrameObject *f, void *closure) { return PyLong_FromLong(PyFrame_GetLineNumber(f)); }
int uwsgi_python_tracer(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) { #ifndef UWSGI_PYPY static uint64_t last_ts = 0; uint64_t now = uwsgi_micros(); uint64_t delta = 0; if (what == PyTrace_LINE) { if (last_ts == 0) { delta = 0; } else { delta = now - last_ts; } last_ts = now; uwsgi_log("[uWSGI Python profiler %llu] file %s line %d: %s argc:%d\n", (unsigned long long)delta, PyString_AsString(frame->f_code->co_filename), PyFrame_GetLineNumber(frame), PyString_AsString(frame->f_code->co_name), frame->f_code->co_argcount); } #endif return 0; }