Created
January 13, 2017 14:54
-
-
Save Elizaveta239/a9774ea5c0f5f05416b84e1cb379edf9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cdef extern from *: | |
ctypedef void freefunc(void *) | |
ctypedef void PyObject | |
ctypedef struct PyCodeObject: | |
int co_argcount; # arguments, except *args */ | |
int co_kwonlyargcount; # keyword only arguments */ | |
int co_nlocals; # local variables */ | |
int co_stacksize; # entries needed for evaluation stack */ | |
int co_flags; # CO_..., see below */ | |
int co_firstlineno; # first source line number */ | |
PyObject *co_code; # instruction opcodes */ | |
PyObject *co_consts; # list (constants used) */ | |
PyObject *co_names; # list of strings (names used) */ | |
PyObject *co_varnames; # tuple of strings (local variable names) */ | |
PyObject *co_freevars; # tuple of strings (free variable names) */ | |
PyObject *co_cellvars; # tuple of strings (cell variable names) */ | |
unsigned char *co_cell2arg; # Maps cell vars which are arguments. */ | |
PyObject *co_filename; # unicode (where it was loaded from) */ | |
PyObject *co_name; # unicode (name, for reference) */ | |
PyObject *co_lnotab; # string (encoding addr<->lineno mapping) See | |
# Objects/lnotab_notes.txt for details. */ | |
void *co_zombieframe; # for optimization only (see frameobject.c) */ | |
PyObject *co_weakreflist; # to support weakrefs to code objects */ | |
void *co_extra; | |
cdef extern from "frameobject.h": | |
ctypedef struct PyFrameObject: | |
PyCodeObject *f_code # code segment | |
PyObject *f_builtins # builtin symbol table (PyDictObject) | |
PyObject *f_globals # global symbol table (PyDictObject) */ | |
PyObject *f_locals # local symbol table (any mapping) */ | |
PyObject **f_valuestack # | |
PyObject **f_stacktop | |
PyObject *f_trace # Trace function */ | |
PyObject *f_exc_type | |
PyObject *f_exc_value | |
PyObject *f_exc_traceback | |
PyObject *f_gen; | |
int f_lasti; #/* Last instruction if called */ | |
int f_lineno; #/* Current line number */ | |
int f_iblock; #/* index in f_blockstack */ | |
char f_executing; #/* whether the frame is still executing */ | |
PyObject *f_localsplus[1]; | |
cdef extern from "code.h": | |
int _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) | |
int _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) | |
cdef extern from "Python.h": | |
void PyObject_Free(void *ptr) | |
void PyObject_Del(PyObject *op) | |
void Py_INCREF(object o) | |
void Py_DECREF(object o) | |
object PyImport_ImportModule(char *name) | |
PyObject* PyObject_CallFunction(PyObject *callable, const char *format, ...) | |
object PyObject_GetAttrString(object o, char *attr_name) | |
cdef extern from "pystate.h": | |
ctypedef PyObject* _PyFrameEvalFunction(PyFrameObject *frame, int exc) | |
ctypedef struct PyInterpreterState: | |
PyInterpreterState *next | |
PyInterpreterState *tstate_head | |
PyObject *modules | |
PyObject *modules_by_index | |
PyObject *sysdict | |
PyObject *builtins | |
PyObject *importlib | |
PyObject *codec_search_path | |
PyObject *codec_search_cache | |
PyObject *codec_error_registry | |
int codecs_initialized | |
int fscodec_initialized | |
int dlopenflags | |
PyObject *builtins_copy | |
PyObject *import_func | |
# Initialized to PyEval_EvalFrameDefault(). | |
_PyFrameEvalFunction eval_frame | |
ctypedef struct PyThreadState: | |
PyThreadState *prev | |
PyThreadState *next | |
PyInterpreterState *interp | |
# ... | |
PyThreadState *PyThreadState_Get() | |
cdef extern from "ceval.h": | |
int _PyEval_RequestCodeExtraIndex(freefunc); | |
PyFrameObject *PyEval_GetFrame() | |
PyObject* PyEval_CallFunction(PyObject *callable, const char *format, ...) | |
PyObject* _PyEval_EvalFrameDefault(PyFrameObject *frame, int exc) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import dis | |
from _pydevd_bundle.pydevd_comm import get_global_debugger | |
from _pydevd_frame_eval.pydevd_frame_tracing import pydev_trace_code_wrapper, update_globals_dict | |
from _pydevd_frame_eval.pydevd_modify_bytecode import insert_code | |
from _pydevd_bundle.pydevd_dont_trace_files import DONT_TRACE | |
def get_breakpoints_for_file(filename): | |
main_debugger = get_global_debugger() | |
breakpoints_for_file = main_debugger.breakpoints.get(filename) | |
return breakpoints_for_file | |
cdef PyObject* get_bytecode_while_frame_eval(PyFrameObject *frame, int exc): | |
filepath = str(<object> frame.f_code.co_filename) | |
skip_file = False | |
breakpoints = None | |
cdef void** extra = NULL | |
for file in DONT_TRACE.keys(): | |
if filepath.endswith(file): | |
skip_file = True | |
break | |
if not skip_file: | |
breakpoints = get_breakpoints_for_file(filepath) | |
_PyCode_GetExtra(<PyObject*> frame.f_code, 0, extra) | |
if extra is not NULL: | |
val = <object>(<PyObject*> extra) | |
print(val) | |
if breakpoints: | |
was_break = False | |
for offset, line in dis.findlinestarts(<object> frame.f_code): | |
if line in breakpoints: | |
was_break = True | |
new_code = insert_code(<object> frame.f_code, pydev_trace_code_wrapper.__code__, line) | |
Py_INCREF(new_code) | |
frame.f_code = <PyCodeObject *> new_code | |
if was_break: | |
dis.dis(new_code) | |
index = _PyEval_RequestCodeExtraIndex(PyObject_Free) | |
print(index) | |
_PyCode_SetExtra(<PyObject*> frame.f_code, index, <PyObject*> "mod") | |
update_globals_dict(<object> frame.f_globals) | |
return _PyEval_EvalFrameDefault(frame, exc) | |
def frame_eval_func(): | |
cdef PyThreadState *state = PyThreadState_Get() | |
state.interp.eval_frame = get_bytecode_while_frame_eval | |
def stop_frame_eval(): | |
cdef PyThreadState *state = PyThreadState_Get() | |
state.interp.eval_frame = _PyEval_EvalFrameDefault |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment