From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5485 invoked by alias); 19 Mar 2012 15:06:06 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 5431 invoked by uid 9514); 19 Mar 2012 15:06:01 -0000 Date: Mon, 19 Mar 2012 15:06:00 -0000 Message-ID: <20120319150601.5416.qmail@sourceware.org> From: pmuldoon@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-pmuldoon-python-backtrace: Implement omit and (bogus, non duck typed) elide function. X-Git-Refname: refs/heads/archer-pmuldoon-python-backtrace X-Git-Reftype: branch X-Git-Oldrev: 0e5e6d2d84fbf0a975c4f83017c845805b7d1ae2 X-Git-Newrev: d34a750b8b79c1260f21e8c25f61b7197448d78f X-SW-Source: 2012-q1/txt/msg00066.txt.bz2 List-Id: 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 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 . */ #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(""); + func = xstrdup (""); 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(""); @@ -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.