예제 #1
0
파일: profiler.c 프로젝트: 20tab/uwsgi
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;
}
예제 #2
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++;
  }
}
예제 #3
0
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);
}
예제 #4
0
파일: profiler.c 프로젝트: sashka/uwsgi
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;
}
예제 #5
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;
}
예제 #6
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;
}
예제 #7
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;
}
예제 #8
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;
}
예제 #9
0
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;
}
예제 #10
0
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);
	}
}
예제 #11
0
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;
}
예제 #12
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;
}
예제 #13
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;
}
예제 #14
0
static PyObject *
frame_getlineno(PyFrameObject *f, void *closure)
{
    return PyLong_FromLong(PyFrame_GetLineNumber(f));
}
예제 #15
0
파일: profiler.c 프로젝트: 20tab/uwsgi
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;
}