static int emit_code_object(PyCodeObject *co) { char buf[MAX_FUNC_NAME + 1]; char *co_name, *co_filename; int co_firstlineno; int sz; #if PY_MAJOR_VERSION >= 3 co_name = PyUnicode_AsUTF8(co->co_name); if (co_name == NULL) return -1; co_filename = PyUnicode_AsUTF8(co->co_filename); if (co_filename == NULL) return -1; #else co_name = PyString_AS_STRING(co->co_name); co_filename = PyString_AS_STRING(co->co_filename); #endif co_firstlineno = co->co_firstlineno; sz = snprintf(buf, MAX_FUNC_NAME / 2, "py:%s", co_name); if (sz < 0) sz = 0; if (sz > MAX_FUNC_NAME / 2) sz = MAX_FUNC_NAME / 2; snprintf(buf + sz, MAX_FUNC_NAME / 2, ":%d:%s", co_firstlineno, co_filename); return vmprof_register_virtual_function(buf, CODE_ADDR_TO_UID(co), 500000); }
static void* get_virtual_ip(char* sp) { /* This returns the address of the code object plus 0x7000000000000000 as the identifier. The mapping from identifiers to string representations of the code object is done elsewhere, namely: * If the code object dies while vmprof is enabled, PyCode_Type.tp_dealloc will emit it. (We don't handle nicely for now the case where several code objects are created and die at the same memory address.) * When _vmprof.disable() is called, then we look around the process for code objects and emit all the ones that we can find (which we hope is very close to 100% of them). */ PyFrameObject *f = *(PyFrameObject **)(sp + mainloop_sp_offset); return (void *)CODE_ADDR_TO_UID(f->f_code); }
static void* get_virtual_ip(char* sp) { PyFrameObject *f = *(PyFrameObject **)(sp + mainloop_sp_offset); return (void *)CODE_ADDR_TO_UID(f->f_code); }