public inbox for archer-commits@sourceware.org help / color / mirror / Atom feed
From: pmuldoon@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-pmuldoon-python-backtrace: Implement omit and (bogus, non duck typed) elide function. Date: Mon, 19 Mar 2012 15:06:00 -0000 [thread overview] Message-ID: <20120319150601.5416.qmail@sourceware.org> (raw) The branch, archer-pmuldoon-python-backtrace has been updated via d34a750b8b79c1260f21e8c25f61b7197448d78f (commit) from 0e5e6d2d84fbf0a975c4f83017c845805b7d1ae2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit d34a750b8b79c1260f21e8c25f61b7197448d78f Author: Phil Muldoon <pmuldoon@redhat.com> Date: Mon Mar 19 15:05:11 2012 +0000 Implement omit and (bogus, non duck typed) elide function. ----------------------------------------------------------------------- Summary of changes: gdb/frame.c | 23 ++++ gdb/frame.h | 6 + gdb/python/py-framefilter.c | 145 +++++++++++++++++++++++---- gdb/python/python.h | 6 +- gdb/stack.c | 18 +++- gdb/testsuite/gdb.python/py-framefilter.c | 3 +- gdb/testsuite/gdb.python/py-framefilter.exp | 4 +- gdb/testsuite/gdb.python/py-framefilter.py | 34 +++++-- 8 files changed, 197 insertions(+), 42 deletions(-) First 500 lines of diff: diff --git a/gdb/frame.c b/gdb/frame.c index e012f2d..3e0cb40 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -127,6 +127,11 @@ struct frame_info /* The reason why we could not set PREV, or UNWIND_NO_REASON if we could. Only valid when PREV_P is set. */ enum unwind_stop_reason stop_reason; + + /* In Python frame-filtering, we can "elide" frames. Store state + (during printing and processing) if this frame has been elided by + another. */ + int elide; }; /* A frame stash used to speed up frame lookups. */ @@ -2217,6 +2222,24 @@ frame_relative_level (struct frame_info *fi) return fi->level; } +int +frame_print_elide (struct frame_info *fi) +{ + if (fi == NULL) + return -1; + else + return fi->elide; +} + +void +set_frame_print_elide (struct frame_info *fi) +{ + if (fi == NULL) + return; + else + fi->elide = 1; +} + enum frame_type get_frame_type (struct frame_info *frame) { diff --git a/gdb/frame.h b/gdb/frame.h index 7b42b56..c027c81 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -428,6 +428,12 @@ extern CORE_ADDR get_frame_args_address (struct frame_info *); for an invalid frame). */ extern int frame_relative_level (struct frame_info *fi); +/* Whether this frame has been marked as elided for printing + purposes. */ +extern int frame_print_elide (struct frame_info *fi); + +extern void set_frame_print_elide (struct frame_info *fi); + /* Return the frame's type. */ extern enum frame_type get_frame_type (struct frame_info *); diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index d156d7f..ea4edfc 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -18,7 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "defs.h" -#include "exceptions.h" #include "objfiles.h" #include "symtab.h" #include "language.h" @@ -247,8 +246,10 @@ find_frame_filter (PyObject *frame, int print_level, } static int -print_frame (PyObject *filter, int print_level, - enum print_what print_what, int print_args, +print_frame (PyObject *filter, + int print_level, + enum print_what print_what, + int print_args, struct ui_out *out, struct value_print_options opts, struct frame_info *frame) @@ -260,18 +261,53 @@ print_frame (PyObject *filter, int print_level, char *func = NULL; char *filename = NULL; int line = 0; + volatile struct gdb_exception except; + + /* First check to see if this frame is to be omitted. */ + if (PyObject_HasAttrString (filter, "omit")) + { + PyObject *result = PyObject_CallMethod (filter, "omit", NULL); + + if (result) + { + int omit = 0; + + if (! PyBool_Check (result)) + { + Py_DECREF (result); + PyErr_SetString (PyExc_RuntimeError, + _("'omit' must return type boolean.")); + goto error; + } + + omit = PyObject_IsTrue (result); + + Py_DECREF (result); + + if (omit == -1) + goto error; + else if (omit) + return 1; + } + else + goto error; + } if (print_level) { if (PyObject_HasAttrString (filter, "level")) { - PyObject *result = PyObject_CallMethod (filter, "level", NULL); + PyObject *result = PyObject_CallMethod (filter, "level", "i", + frame_relative_level (frame), + NULL); if (result) { level = PyLong_AsLong (result); Py_DECREF (result); } + else + goto error; } else level = frame_relative_level (frame); @@ -286,6 +322,8 @@ print_frame (PyObject *filter, int print_level, address = PyLong_AsLong (result); Py_DECREF (result); } + else + goto error; } else address = 0; @@ -311,15 +349,21 @@ print_frame (PyObject *filter, int print_level, if (result) { char *dup = PyString_AsString (result); - if (dup) - func = xstrdup (dup); - else - return 0; + if (! dup) + { + Py_DECREF (result); + goto error; + } + + func = xstrdup (dup); + Py_DECREF (result); } + else + goto error; } else - func = xstrdup("<unknown>"); + func = xstrdup ("<unknown>"); annotate_frame_function_name (); ui_out_field_string (out, "func", func); @@ -331,12 +375,19 @@ print_frame (PyObject *filter, int print_level, if (result) { char *dup = PyString_AsString (result); - if (dup) - filename = xstrdup (dup); - else - return 0; + + if (! dup) + { + Py_DECREF (result); + goto error; + } + + filename = xstrdup (dup); + Py_DECREF (result); } + else + goto error; } else func = xstrdup("<unknown function>"); @@ -357,6 +408,8 @@ print_frame (PyObject *filter, int print_level, line = PyLong_AsLong (result); Py_DECREF (result); } + else + goto error; } else line = 0; @@ -369,10 +422,55 @@ print_frame (PyObject *filter, int print_level, ui_out_text (out, "\n"); annotate_frame_end (); + if (PyObject_HasAttrString (filter, "elide")) + { + PyObject *result = PyObject_CallMethod (filter, "elide", NULL); + + if (result) + { + struct frame_info *restart = NULL; + struct frame_info *current = NULL; + /* Fix result here. */ + TRY_CATCH (except, RETURN_MASK_ALL) + { + restart = frame_object_to_frame_info (result); + } + if (except.reason > 0) + { + Py_DECREF (result); + PyErr_SetString (PyExc_RuntimeError, + except.message); + goto error; + } + if (! restart) + { + Py_DECREF (result); + PyErr_SetString (PyExc_RuntimeError, + _("Cannot locate frame to continue backtrace.")); + goto error; + } + if (restart != frame) + { + current=get_prev_frame (frame); + while (current!=restart) + { + set_frame_print_elide (current); + current = get_prev_frame (current); + } + } + } + else + goto error; + } + xfree (func); xfree (filename); - return 1; + + error: + xfree (func); + xfree (filename); + return 0; } int @@ -386,6 +484,7 @@ apply_frame_filter (struct frame_info *frame, int print_level, int result = 0; int print_result = 0; struct value_print_options opts; + int success = 0; cleanups = ensure_python_env (gdbarch, current_language); @@ -396,32 +495,34 @@ apply_frame_filter (struct frame_info *frame, int print_level, /* Find the constructor. */ filter = find_frame_filter (frame_obj, print_level, print_what, print_args); Py_DECREF (frame_obj); + make_cleanup_py_decref (filter); if (! filter || filter == Py_None) goto done; get_user_print_options (&opts); - print_result = print_frame (filter, print_level, print_what, - print_args, out, opts, frame); + success = print_frame (filter, print_level, print_what, + print_args, out, opts, frame); - if (print_result) - result = 1; - else + /* 'print_frame' can return a frame to "resume" from, in the case + that frames have been elided. If the return value is NULL, also + check to see if this was because a Python error occurred. */ + if (success == 0 && PyErr_Occurred()) gdbpy_print_stack (); done: do_cleanups (cleanups); - return result; + return success; } #else /* HAVE_PYTHON */ -int +struct frame_info * apply_frame_filter (struct frame_info *frame, int print_level, enum print_what print_what, int print_args, struct ui_out *out) { - return 0; + return NULL; } #endif /* HAVE_PYTHON */ diff --git a/gdb/python/python.h b/gdb/python/python.h index 0344aa9..32a5653 100644 --- a/gdb/python/python.h +++ b/gdb/python/python.h @@ -39,8 +39,10 @@ int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, const struct value_print_options *options, const struct language_defn *language); -int apply_frame_filter (struct frame_info *frame, int print_level, - enum print_what print_what, int print_args, +int apply_frame_filter (struct frame_info *frame, + int print_level, + enum print_what print_what, + int print_args, struct ui_out *out); void preserve_python_values (struct objfile *objfile, htab_t copied_types); diff --git a/gdb/stack.c b/gdb/stack.c index bdd63f4..9ae4290 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -762,12 +762,17 @@ print_frame_info (struct frame_info *frame, int print_level, struct symtab_and_line sal; int source_print; int location_print; - int result; struct ui_out *uiout = current_uiout; - result = apply_frame_filter (frame, 1, LOCATION, 1, current_uiout); - if (result) - return; + /* If a previous frame elided this one, do not run the frame + filters. */ + if (! frame_print_elide (frame)) + { + int result = apply_frame_filter (frame, 1, LOCATION, 1, + current_uiout); + if (result) + return; + } if (get_frame_type (frame) == DUMMY_FRAME || get_frame_type (frame) == SIGTRAMP_FRAME @@ -783,7 +788,7 @@ print_frame_info (struct frame_info *frame, int print_level, to list for this frame. */ if (print_level) { - ui_out_text (uiout, "#"); + ui_out_text (uiout, "#"); ui_out_field_fmt_int (uiout, 2, ui_left, "level", frame_relative_level (frame)); } @@ -1128,6 +1133,9 @@ print_frame (struct frame_info *frame, int print_level, list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "frame"); + if (frame_print_elide (frame)) + ui_out_spaces (uiout, 4); + if (print_level) { ui_out_text (uiout, "#"); diff --git a/gdb/testsuite/gdb.python/py-framefilter.c b/gdb/testsuite/gdb.python/py-framefilter.c index 26f561f..6113716 100644 --- a/gdb/testsuite/gdb.python/py-framefilter.c +++ b/gdb/testsuite/gdb.python/py-framefilter.c @@ -37,7 +37,7 @@ void funca(void) count++; funcb(count); } - + end_func(); return; } @@ -83,4 +83,3 @@ main() { func5(3); } - diff --git a/gdb/testsuite/gdb.python/py-framefilter.exp b/gdb/testsuite/gdb.python/py-framefilter.exp index 73c1ba5..a3b1126 100644 --- a/gdb/testsuite/gdb.python/py-framefilter.exp +++ b/gdb/testsuite/gdb.python/py-framefilter.exp @@ -40,6 +40,6 @@ set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py] gdb_test_no_output "python execfile ('${remote_python_file}')" gdb_test_no_output "python gdb.frame_filters.append(register_frame_filters)" gdb_breakpoint [gdb_get_line_number "Backtrace end breakpoint"] -gdb_continue_to_breakpoint "Bactrace end breakpoint" -gdb_test "bt" "#1.*in end_func.*#23.*in func1.*#27.*in main ().*" +gdb_continue_to_breakpoint "Backtrace end breakpoint" +gdb_test "bt" "#0.*in end_func.*#22.*in func1.*Composite frame func3.*#27.*in main ().*" remote_file host delete ${remote_python_file} diff --git a/gdb/testsuite/gdb.python/py-framefilter.py b/gdb/testsuite/gdb.python/py-framefilter.py index b7ee5c5..a3afe1a 100644 --- a/gdb/testsuite/gdb.python/py-framefilter.py +++ b/gdb/testsuite/gdb.python/py-framefilter.py @@ -16,8 +16,6 @@ # This file is part of the GDB testsuite. It tests Python-based # frame-filters. -flevel = 0 - class Main_filter: "Example main () filter" @@ -26,16 +24,34 @@ class Main_filter: self.what = what self.lvl = level self.args = args - + + def omit (self): + fname = str (self.frame.function()) + if fname == "func2": + return True + else: + return False + + def elide (self): + fname = str (self.frame.function()) + frame = self.frame + + if fname == "func3": + frame = frame.older() + frame = frame.older() + frame = frame.older() + + return frame def function (self): - return str (self.frame.function()) + fname = str (self.frame.function()) + if fname == "func3": + return "Composite frame " + str(self.frame.function()) + else: + return str (self.frame.function()) - def level (self): - global flevel - rlevel = flevel - flevel = flevel + 1 - return rlevel + def level (self, level): + return level def address (self): return self.frame.pc() hooks/post-receive -- Repository for Project Archer.
reply other threads:[~2012-03-19 15:06 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20120319150601.5416.qmail@sourceware.org \ --to=pmuldoon@sourceware.org \ --cc=archer-commits@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).