From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17922 invoked by alias); 21 Jun 2012 19:25:58 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 17863 invoked by uid 9514); 21 Jun 2012 19:25:56 -0000 Date: Thu, 21 Jun 2012 19:25:00 -0000 Message-ID: <20120621192556.17846.qmail@sourceware.org> From: pmuldoon@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-pmuldoon-python-backtrace: Use python FrameIterator. Remove list lookup references. Write invoke method in Python. Add testsuite changes to include insertion of a dummy frame. X-Git-Refname: refs/heads/archer-pmuldoon-python-backtrace X-Git-Reftype: branch X-Git-Oldrev: 9970e390718512d3b4ff0d315bedb787dd497c0b X-Git-Newrev: 94426f022d3e5a4e9c7b7d0a25c57a334ab6497d X-SW-Source: 2012-q2/txt/msg00062.txt.bz2 List-Id: The branch, archer-pmuldoon-python-backtrace has been updated via 94426f022d3e5a4e9c7b7d0a25c57a334ab6497d (commit) from 9970e390718512d3b4ff0d315bedb787dd497c0b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 94426f022d3e5a4e9c7b7d0a25c57a334ab6497d Author: Phil Muldoon Date: Thu Jun 21 20:24:57 2012 +0100 Use python FrameIterator. Remove list lookup references. Write invoke method in Python. Add testsuite changes to include insertion of a dummy frame. ----------------------------------------------------------------------- Summary of changes: gdb/data-directory/Makefile.in | 3 +- gdb/python/lib/gdb/FrameIterator.py | 12 +- gdb/python/lib/gdb/FrameWrapper.py | 3 + gdb/python/lib/gdb/command/frame_filters.py | 6 +- gdb/python/py-framefilter.c | 250 +++------------------------ gdb/testsuite/gdb.python/py-framefilter.exp | 7 +- gdb/testsuite/gdb.python/py-framefilter.py | 71 +++++++- 7 files changed, 109 insertions(+), 243 deletions(-) First 500 lines of diff: diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in index 7dc7fb3..ea2c682 100644 --- a/gdb/data-directory/Makefile.in +++ b/gdb/data-directory/Makefile.in @@ -56,8 +56,9 @@ PYTHON_FILES = \ gdb/types.py \ gdb/printing.py \ gdb/prompt.py \ - gdb/FrameWrapper.py \ gdb/FrameFilter.py \ + gdb/FrameIterator.py \ + gdb/FrameWrapper.py \ gdb/command/__init__.py \ gdb/command/frame_filters.py \ gdb/command/pretty_printers.py \ diff --git a/gdb/python/lib/gdb/FrameIterator.py b/gdb/python/lib/gdb/FrameIterator.py index 4f14e8a..5816c57 100644 --- a/gdb/python/lib/gdb/FrameIterator.py +++ b/gdb/python/lib/gdb/FrameIterator.py @@ -1,17 +1,23 @@ +import gdb +import itertools + class FrameIterator(object): """A frame iterator. Iterates over gdb.Frames or objects that conform to that interface.""" def __init__ (self, frame_obj): - "Initialize a FrameIterator. FRAME_OBJ is the starting - frame." + """Initialize a FrameIterator. FRAME_OBJ is the starting + frame.""" super(FrameIterator, self).__init__() - self.frame = frame + self.frame = frame_obj def __iter__ (self): return self + def __getitem__(self,index): + return next(itertools.islice(self.frame,index,index+1)) + def next (self): result = self.frame if result is None: diff --git a/gdb/python/lib/gdb/FrameWrapper.py b/gdb/python/lib/gdb/FrameWrapper.py index 11f69ed..0aa7870 100644 --- a/gdb/python/lib/gdb/FrameWrapper.py +++ b/gdb/python/lib/gdb/FrameWrapper.py @@ -79,3 +79,6 @@ class FrameWrapper: def inferior_frame (self): return self.frame + + def older(self): + return self.frame.older() diff --git a/gdb/python/lib/gdb/command/frame_filters.py b/gdb/python/lib/gdb/command/frame_filters.py index c1ea05c..3b76bf4 100644 --- a/gdb/python/lib/gdb/command/frame_filters.py +++ b/gdb/python/lib/gdb/command/frame_filters.py @@ -19,6 +19,7 @@ import gdb import copy import gdb.FrameFilter +from gdb.FrameIterator import FrameIterator def _parse_arg (cmd_name, arg): """ Internal Worker function to take an argument and return a @@ -151,14 +152,15 @@ def _sort_list (): sorted_frame_filters = filter (_get_enabled, sorted_frame_filters) return sorted_frame_filters -def invoke (frame_iterator): +def invoke (frame): """ Public internal function that will execute the chain of frame filters. Each filter is executed in priority order. Arguments: frame_iterator: An iterator of frames. """ - sorted_list = sort_list() + sorted_list = _sort_list() + frame_iterator = FrameIterator (frame) for ff in sorted_list: frame_iterator = ff[1].filter (frame_iterator) diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index 2991364..96a41a5 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -32,196 +32,6 @@ #ifdef HAVE_PYTHON #include "python-internal.h" -/* Helper function for find_frame_filter which iterates over a list, - calls each function and inspects output. This will return a filter - object if one of the filters registers interest in FRAME. If no - frame filter is found, it will return None. On error, it will set - the Python error and return NULL. */ - -static PyObject * -search_frame_filter_list (PyObject *list, PyObject *frame, - int limit) - -{ - Py_ssize_t list_size, list_index; - PyObject *filter = NULL; - PyObject *slimit = PyLong_FromLong (limit); - - if (! slimit) - return NULL; - - list_size = PyList_Size (list); - for (list_index = 0; list_index < list_size; list_index++) - { - PyObject *function; - - function = PyList_GetItem (list, list_index); - if (! function) - return NULL; - - /* Skip if disabled. */ - if (PyObject_HasAttr (function, gdbpy_enabled_cst)) - { - PyObject *attr = PyObject_GetAttr (function, gdbpy_enabled_cst); - int cmp; - - if (!attr) - return NULL; - cmp = PyObject_IsTrue (attr); - - Py_DECREF (attr); - if (cmp == -1) - return NULL; - - if (!cmp) - continue; - } - - filter = PyObject_CallFunctionObjArgs (function, frame, slimit, NULL); - - Py_DECREF (slimit); - if (! filter) - { - Py_DECREF (slimit); - return NULL; - } - else if (filter != Py_None) - { - Py_DECREF (slimit); - return filter; - } - - Py_DECREF (filter); - } - - Py_RETURN_NONE; -} - - -/* Subroutine of find_frame_filter to simplify it. Look for a frame - filter for FRAME in the gdb module. The result is NULL if there's - an error and the search should be terminated. The result is - Py_None, if no frame filter is found. Otherwise the result is the - frame filter function, suitably inc-ref'd. */ - -static PyObject * -find_frame_filter_from_gdb (PyObject *frame, int limit) -{ - PyObject *filter_list; - PyObject *function; - - /* Fetch the global frame filter list. */ - if (! PyObject_HasAttrString (gdb_module, "frame_filters")) - Py_RETURN_NONE; - - filter_list = PyObject_GetAttrString (gdb_module, "frame_filters"); - if (filter_list == NULL || ! PyList_Check (filter_list)) - { - Py_XDECREF (filter_list); - Py_RETURN_NONE; - } - - function = search_frame_filter_list (filter_list, frame, limit); - Py_XDECREF (filter_list); - return function; -} -/* Subroutine of find_frame_filter to simplify it. Look for a frame - filter for FRAME in all objfiles. The result is NULL if there's an - error and the search should be terminated. The result is Py_None - if no frame filter found. Otherwise the result is the - pretty-printer function. */ - -static PyObject * -find_frame_filter_from_objfiles (PyObject *frame, int limit) -{ - PyObject *filter_list; - PyObject *function; - struct objfile *obj; - - ALL_OBJFILES (obj) - { - PyObject *objf = objfile_to_objfile_object (obj); - if (!objf) - { - /* Ignore the error and continue. */ - PyErr_Clear (); - continue; - } - - filter_list = objfpy_get_frame_filters (objf, NULL); - - function = search_frame_filter_list (filter_list, frame, limit); - - Py_XDECREF (filter_list); - - /* If there is an error in any objfile list, abort the search and exit. */ - if (! function) - return NULL; - - if (function != Py_None) - return function; - - Py_DECREF (function); - } - - Py_RETURN_NONE; -} - -/* Subroutine of find_pretty_printer to simplify it. Look for a frame - filter for FRAME in the current program space. The result is NULL - if there's an error and the search should be terminated. The - result is Py_None, no frame filter was found. Otherwise the result - is the pretty-printer function. */ - -static PyObject * -find_frame_filter_from_progspace (PyObject *frame, int limit) -{ - PyObject *filter_list; - PyObject *function; - PyObject *obj = pspace_to_pspace_object (current_program_space); - - if (!obj) - return NULL; - filter_list = pspy_get_frame_filters (obj, NULL); - - function = search_frame_filter_list (filter_list, frame, limit); - - Py_XDECREF (filter_list); - return function; -} - - -/* Find the frame filter constructor function for FRAME. If no - frame filter exists, return None. If one exists, return a new - reference. On error, set the Python error and return NULL. */ - -static PyObject * -find_frame_filter (PyObject *frame, int limit) -{ - PyObject *function = NULL; - - /* Look at the frame filter list for each objfile - in the current program-space. */ - function = find_frame_filter_from_objfiles (frame, limit); - - if (function == NULL || function != Py_None) - goto exit_func; - Py_DECREF (function); - - /* Look at the frame filter list for the current program-space. */ - function = find_frame_filter_from_progspace (frame, limit); - - if (function == NULL || function != Py_None) - goto exit_func; - Py_DECREF (function); - - /* Look at the frame filter list in the gdb module. */ - function = find_frame_filter_from_gdb (frame, limit) ; - -exit_func: - return function; -} - static int py_print_locals (PyObject *filter, struct value_print_options opts) @@ -541,22 +351,22 @@ py_print_frame (PyObject *filter, if (! result) goto error; - frame = frame_object_to_frame_info (result); - if (! frame) + if (result == Py_None) + gdbarch = target_gdbarch; + else { - Py_DECREF (result); - goto error; + frame = frame_object_to_frame_info (result); + if (! frame) + { + Py_DECREF (result); + goto error; + } + gdbarch = get_frame_arch (frame); } - Py_DECREF (result); - gdbarch = get_frame_arch (frame); } else - { - PyErr_SetString (PyExc_RuntimeError, - _("frame filter must implement inferior_frame callback.")); - goto error; - } + gdbarch = target_gdbarch; if (PyObject_HasAttrString (filter, "elide")) { @@ -743,46 +553,38 @@ apply_frame_filter (struct frame_info *frame, int print_level, { struct gdbarch *gdbarch = get_frame_arch (frame); struct cleanup *cleanups; - PyObject *frame_obj, *filter, *frame_iter, *iterable; int result = 0; int print_result = 0; struct value_print_options opts; int success = 0; - PyObject *filter_list; - PyObject *sort_func; - PyObject *sort; PyObject *module; + PyObject *sort_func; + PyObject *iterable; + PyObject *frame_obj; cleanups = ensure_python_env (gdbarch, current_language); frame_obj = frame_info_to_frame_object (frame); if (! frame_obj) goto done; - module = PyImport_AddModule ("__main__"); - sort_func = PyObject_GetAttrString (module, "sort_list"); - filter_list = PyObject_GetAttrString (gdb_module, "frame_filters"); - sort = PyObject_CallFunctionObjArgs (sort_func, filter_list, NULL); - if (PyErr_Occurred()) + + module = PyImport_AddModule ("gdb.command.frame_filters"); + + sort_func = PyObject_GetAttrString (module, "invoke"); + if (!sort_func) { - gdbpy_print_stack (); - return 0; + Py_DECREF (module); + goto done; } - /* Build the filter list ordered by priority. */ - - /* Find the constructor. */ - filter = find_frame_filter (frame_obj, count); + iterable = PyObject_CallFunctionObjArgs (sort_func, frame_obj, NULL); + Py_DECREF (sort_func); Py_DECREF (frame_obj); - - make_cleanup_py_decref (filter); - if (! filter || filter == Py_None) + Py_DECREF (module); + if (!iterable || PyErr_Occurred()) goto done; - + get_user_print_options (&opts); - iterable = PyObject_CallMethod (filter, "invoke", NULL); - if (! iterable) - goto done; - make_cleanup_py_decref (iterable); /* Is it an iterator */ diff --git a/gdb/testsuite/gdb.python/py-framefilter.exp b/gdb/testsuite/gdb.python/py-framefilter.exp index 362be5b..7fd44d7 100644 --- a/gdb/testsuite/gdb.python/py-framefilter.exp +++ b/gdb/testsuite/gdb.python/py-framefilter.exp @@ -37,12 +37,11 @@ if ![runto_main ] then { } set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py] -gdb_test_no_output "set python print-stack full" gdb_test_no_output "python execfile ('${remote_python_file}')" -gdb_test_no_output "python gdb.frame_filters.append(FrameFilter)" gdb_breakpoint [gdb_get_line_number "Backtrace end breakpoint"] gdb_continue_to_breakpoint "Backtrace end breakpoint" -gdb_test "bt" "#0.*in end_func.*#22.*in func1.*Composite frame func3.*#27.*in main ().*" -gdb_test "bt full" "#0.*in end_func.*#22.*in func1.*Composite frame func3.*#27.*in main ().*" + +gdb_test "bt" "#-1.*in Dummy function.*#22.*in 1cnuf.*#27.*in niam ().*" +gdb_test "bt" "#-1.*in Dummy function.*#22.*in 1cnuf.*#27.*in niam ().*" 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 b876805..15f7a74 100644 --- a/gdb/testsuite/gdb.python/py-framefilter.py +++ b/gdb/testsuite/gdb.python/py-framefilter.py @@ -37,16 +37,69 @@ class Reverse_Function (FrameWrapper): else: return False +class Dummy: + def __init__(self, nextframe): + self.nextframe = nextframe + + def omit (self): + return False + + def elide (self): + return False + + def function (self): + return "Dummy function" + + def address (self): + return 0x123 + + def filename (self): + return "Dummy filename" + + def frame_args (self): + return [] + + def frame_locals (self): + return [] + + def line (self): + return 0 + + def older (self): + return self.nextframe + + def inferior_frame (self): + return None + +class FrameAdd (): + + def __init__ (self): + self.name = "Add" + self.priority = 10 + self.enabled = True + gdb.frame_filters [self.name] = self + + def filter (self, frame_iter): + for f in frame_iter: + nextv = f + break + dummies = [Dummy(nextv)] + frame_iter = itertools.chain (dummies, + frame_iter) + return frame_iter + class FrameFilter (): - def __init__ (self, iterator, limit): - self.iterator = iterator - self.limit = limit + def __init__ (self): + self.name = "Reverse" + self.priority = 100 + self.enabled = True + gdb.frame_filters [self.name] = self - def __new__ (self): - return self; + def filter (self, frame_iter): + frame_iter = itertools.imap (Reverse_Function, + frame_iter) + return frame_iter - def invoke (self): - iter = itertools.imap (Reverse_Function, - self.iterator) - return iter +FrameAdd() +FrameFilter() hooks/post-receive -- Repository for Project Archer.