Repository navigation
Improve sys.settrace to help support debugpy / pdb debugging - #8767
andrewleech wants to merge 2 commits into
Conversation
16bd204 to
e027113
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #8767 +/- ##
==========================================
- Coverage 98.46% 98.39% -0.08%
==========================================
Files 176 176
Lines 22784 22816 +32
==========================================
+ Hits 22435 22450 +15
- Misses 349 366 +17 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Requires micropython to be compiled with MICROPY_PY_SYS_SETTRACE. Also requires micropython/micropython#8767
Requires micropython to be compiled with MICROPY_PY_SYS_SETTRACE. Also requires micropython/micropython#8767
Requires micropython to be compiled with MICROPY_PY_SYS_SETTRACE. Also requires micropython/micropython#8767
| MP_DEFINE_CONST_FUN_OBJ_0(mp_sys_gettrace_obj, mp_sys_gettrace); | ||
|
|
||
| // _getframe(): Return current frame object. | ||
| STATIC mp_obj_t mp_sys_getframe(size_t n_args, const mp_obj_t *args) { |
There was a problem hiding this comment.
please call it mp_sys__getframe
| if (attr == MP_QSTR___code__) { | ||
| mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in); | ||
| mp_obj_code_t *code = MP_OBJ_TO_PTR(mp_obj_new_code(self->context, self->rc)); | ||
| if (code != NULL) { |
| switch (attr) { | ||
| case MP_QSTR_f_back: | ||
| dest[0] = mp_const_none; | ||
| if (o->code_state->prev_state) { | ||
| if (!o->code_state->prev_state->frame) { |
There was a problem hiding this comment.
did you find a case where this could be NULL? maybe it needs a test...
| dest[0] = o->trace_obj; | ||
| break; | ||
| case MP_QSTR_f_locals: | ||
| dest[0] = MP_OBJ_FROM_PTR(o->code->dict_locals); |
There was a problem hiding this comment.
is this needed? locals in uPy doesn't work well
There was a problem hiding this comment.
can we just return an empty dict instead?
| @@ -274,6 +292,7 @@ mp_obj_t mp_obj_new_frame(const mp_code_state_t *code_state) { | |||
| o->lineno = mp_prof_bytecode_lineno(rc, o->lasti); | |||
| o->trace_opcodes = false; | |||
| o->callback = MP_OBJ_NULL; | |||
| o->trace_obj = MP_OBJ_NULL; | |||
| @@ -60,7 +61,9 @@ mp_obj_t mp_obj_new_frame(const mp_code_state_t *code_state); | |||
|
|
|||
| // This is the implementation for the sys.settrace | |||
| mp_obj_t mp_prof_settrace(mp_obj_t callback); | |||
| mp_obj_t mp_prof_gettrace(); | |||
| @@ -313,6 +332,33 @@ mp_obj_t mp_prof_settrace(mp_obj_t callback) { | |||
| return mp_const_none; | |||
| } | |||
|
|
|||
| mp_obj_t mp_prof_gettrace() { | |||
| return prof_trace_cb; | ||
| } | ||
|
|
||
| mp_obj_t mp_prof_get_frame(int depth) { |
There was a problem hiding this comment.
can we change int to size_t to indicate it can't be negative?
Requires micropython to be compiled with MICROPY_PY_SYS_SETTRACE. Also requires micropython/micropython#8767
f3c6bf2 to
c32fec4
Compare
|
Code size report: |
Re-enable binascii.crc32()
|
This is an automated heads-up that we've just merged a Pull Request See #13763 A search suggests this PR might apply the STATIC macro to some C code. If it Although this is an automated message, feel free to @-reply to me directly if |
Requires micropython to be compiled with MICROPY_PY_SYS_SETTRACE. Also requires micropython/micropython#8767
0bbcb6e to
e0237a8
Compare
Add sys.gettrace() to mirror settrace, add sys._getframe() for stack frame inspection, and enable sys.settrace() by default on unix standard variant. These additions provide the baseline infrastructure needed for pdb and debugpy to function on MicroPython. Signed-off-by: Andrew Leech <[email protected]>
e0237a8 to
3280c2a
Compare
…#8767) Improve sys.settrace to support debugpy/pdb debugging: adds sys.settrace, sys.gettrace, sys._getframe, frame.f_trace, and enables settrace on the unix standard variant.
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
A raising callback leaves mp_prof_callback_invoke through an nlr jump, so mp_prof_is_executing stayed set for the rest of the process. Every trace hook in the VM tests that flag, so no callback was ever invoked again while sys.settrace() and sys.gettrace() went on reporting success: tracing was silently and permanently off, and a fresh sys.settrace() could not recover it. With assertions enabled the same state trips assert(!mp_prof_is_executing) in mp_prof_frame_enter. The call is now wrapped in nlr_push/nlr_pop; the exception path clears the guard, unsets the trace callback and re-raises. Unsetting matches CPython, and it is what makes the state after a raise recoverable rather than merely different: a callback that raised once is on an error path and would raise again on every subsequent line, which on a device is unrecoverable. A debugger that means to keep tracing re-installs explicitly. TRACE_TICK now also requires the global callback to still be set. Without it "unset" does not unset: frames already on the stack hold the callback the tracer returned for them and go on calling it, so sys.settrace(None) did not stop tracing the frames that were running. A deliberate raise from a trace callback is how a debugger unwinds a target out of a frame it is stopped in - with no second thread and a message pump that runs inside the trace function, it is the only mechanism available. tests/misc/sys_settrace_raise.py covers propagation into the traced program, the unset, that a following sys.settrace() traces exactly as much as it did before the raise, and settrace(None) called from inside a traced frame. It has no .exp file deliberately: the output is identical under CPython, so the test runner compares the two. Signed-off-by: Andrew Leech <[email protected]>
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767 Signed-off-by: Andrew Leech <[email protected]>
139da48 to
a764b6c
Compare
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767 Signed-off-by: Andrew Leech <[email protected]>
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
sys.settrace: gettrace, _getframe, f_trace support (PR micropython#8767) MBM-PR: 8767 MBM-URL: micropython#8767
Companion support for micropython/micropython-lib#1022 & micropython/micropython-lib#499
Requires micropython be built with
MICROPY_PY_SYS_SETTRACEeg. unix standard variantIncludes:
sys/settrace: Add sys._getframe() function.
Refer to https://docs.python.org/3/library/sys.html#sys._getframe
sys/settrace: Add frame.f_trace object support.
f_traceholds a python obj on the frame, used inbdbto track active trace function for call stack.