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: Add sort and invoke Python commands. Use a dictionary instead of a list of frame filters. Document python commands in comments. Date: Thu, 21 Jun 2012 11:11:00 -0000 [thread overview] Message-ID: <20120621111128.6178.qmail@sourceware.org> (raw) The branch, archer-pmuldoon-python-backtrace has been updated via 66f3298ad50418f3ca64c0c7200f2d5854c00b64 (commit) from 9cb749c41529373b3e12253f066a722b02aaf992 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 66f3298ad50418f3ca64c0c7200f2d5854c00b64 Author: Phil Muldoon <pmuldoon@redhat.com> Date: Thu Jun 21 12:10:39 2012 +0100 Add sort and invoke Python commands. Use a dictionary instead of a list of frame filters. Document python commands in comments. ----------------------------------------------------------------------- Summary of changes: gdb/data-directory/Makefile.in | 3 +- gdb/python/lib/gdb/FrameFilter.py | 8 +- gdb/python/lib/gdb/command/frame_filters.py | 201 +++++++++++++++++++-------- gdb/python/py-framefilter.c | 14 ++ gdb/python/py-objfile.c | 8 +- gdb/python/py-progspace.c | 8 +- gdb/python/python.c | 2 +- 7 files changed, 174 insertions(+), 70 deletions(-) First 500 lines of diff: diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in index 86b1198..7dc7fb3 100644 --- a/gdb/data-directory/Makefile.in +++ b/gdb/data-directory/Makefile.in @@ -57,11 +57,12 @@ PYTHON_FILES = \ gdb/printing.py \ gdb/prompt.py \ gdb/FrameWrapper.py \ + gdb/FrameFilter.py \ gdb/command/__init__.py \ + gdb/command/frame_filters.py \ gdb/command/pretty_printers.py \ gdb/command/prompt.py \ gdb/command/explore.py \ - gdb/command/upto.py FLAGS_TO_PASS = \ "prefix=$(prefix)" \ diff --git a/gdb/python/lib/gdb/FrameFilter.py b/gdb/python/lib/gdb/FrameFilter.py index 2ce909f..4ce8497 100644 --- a/gdb/python/lib/gdb/FrameFilter.py +++ b/gdb/python/lib/gdb/FrameFilter.py @@ -6,8 +6,12 @@ class FrameFilter(): priority = 100 enabled = True - def __init__(self, next_filter): - self.next_filter = next_filter + def __init__(self, name, pri, enb): + self.name = name + self.priority = pri + self.enabled = enb + gdb.frame_filters[name] = self + def filter(iter): return iter diff --git a/gdb/python/lib/gdb/command/frame_filters.py b/gdb/python/lib/gdb/command/frame_filters.py index fb712fb..c1ea05c 100644 --- a/gdb/python/lib/gdb/command/frame_filters.py +++ b/gdb/python/lib/gdb/command/frame_filters.py @@ -18,8 +18,17 @@ import gdb import copy +import gdb.FrameFilter def _parse_arg (cmd_name, arg): + """ Internal Worker function to take an argument and return a + tuple of arguments. + + Arguments: + cmd_name: Name of the command invoking this function. + args: The argument as a string + """ + argv = gdb.string_to_argv(arg); argc = len(argv) if argc != 2: @@ -32,29 +41,66 @@ def _parse_arg (cmd_name, arg): return (object_list, argument) def _get_priority(filter_item): - if hasattr(filter_item, "priority"): - return filter_item.priority + """ Internal Worker function to return the frame-filter's priority. + + Arguments: + filter_item: A tuple, with the first element being the name, + and the second being the frame-filter object. + """ + if hasattr(filter_item[1], "priority"): + return filter_item[1].priority else: return 1000 def _set_priority(filter_item, priority): + """ Internal Worker function to set the frame-filter's priority. + + Arguments: + filter_item: A tuple, with the first element being the name, + and the second being the frame-filter object. + priority: The priority to assign as an integer. + """ + if priority < 0 and priority > 10000: raise SyntaxError("Priority must be between 0 - 10000") if hasattr(filter_item, "priority"): filter_item.priority = priority def _get_enabled(filter_item): - if hasattr(filter_item, "enabled"): - return filter_item.enabled + """ Internal Worker function to return the frame-filter's enabled + state. + + Arguments: + filter_item: A tuple, with the first element being the name, + and the second being the frame-filter object. + """ + + if hasattr(filter_item[1], "enabled"): + return filter_item[1].enabled else: return True def _set_enabled(filter_item, state): + """ Internal Worker function to set the frame-filter's enabled + state. + + Arguments: + filter_item: A tuple, with the first element being the name, + and the second being the frame-filter object. + state: True or False, depending on desired state. + """ + if hasattr(filter_item, "enabled"): filter_item.enabled = state def _get_name (frame_filter): - """Return the filter's name.""" + """ Internal Worker function to return the name of the + frame-filter. + + Arguments: + filter_item: A tuple, with the first element being the name, + and the second being the frame-filter object. + """ if hasattr(frame_filter, "name"): return frame_filter.name if hasattr(frame_filter, "__name__"): @@ -62,12 +108,67 @@ def _get_name (frame_filter): # Deal with anonymous objects/functions return "Unknown" +def _return_list (name): + """ Internal Worker function to return the frame-filter name, + depending on the name supplied as an argument. If the name is not + "global" or "progspace", it is assumed to name and object-file. + + Arguments: + name: The name of the list, as specified by GDB user commands. + """ + + if name == "global": + return gdb.frame_filters + else: + if name == "progspace": + cp = gdb.current_progspace() + return cp.frame_filters + else: + for objfile in gdb.objfiles(): + if name == objfile.filename: + return objfile.frame_filters + + msg = "Cannot find frame-filter dictionary for '" + name + "'" + raise gdb.GdbError(msg) + +def _sort_list (): + """ Internal Worker function to merge all known frame-filter + lists, prune any filters with the state set to "disabled", and + sort the list on the frame-filter's "priority" attribute. + """ + + all_filters = [] + for objfile in gdb.objfiles(): + all_filters = all_filters + objfile.frame_filters.items() + cp = gdb.current_progspace() + + all_filters = all_filters + cp.frame_filters.items() + all_filters = all_filters + gdb.frame_filters.items() + + sorted_frame_filters = copy.copy(all_filters) + sorted_frame_filters.sort(key = _get_priority, + reverse = True) + sorted_frame_filters = filter (_get_enabled, sorted_frame_filters) + return sorted_frame_filters + +def invoke (frame_iterator): + """ 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() + for ff in sorted_list: + frame_iterator = ff[1].filter (frame_iterator) + + return frame_iterator + class InfoFrameFilter(gdb.Command): """GDB command to list all registered frame-filters. Usage: info frame-filters """ - @staticmethod def enabled_string(state): """Return "Yes" if PRINTER is enabled, otherwise "No".""" @@ -82,19 +183,18 @@ class InfoFrameFilter(gdb.Command): def list_frame_filters(self, frame_filters): """Print a list of frame_filters.""" - sorted_frame_filters = copy.copy(frame_filters) + sorted_frame_filters = frame_filters.items() sorted_frame_filters.sort(key = _get_priority, reverse = True) print " Priority Enabled Name" print " ======== ======= ====" for frame_filter in sorted_frame_filters: priority = '{:<8}'.format(str(_get_priority (frame_filter))) - name = _get_name(frame_filter) + name = frame_filter[0] enabled = '{:<7}'.format(self.enabled_string(_get_enabled(frame_filter))) print " %s %s %s" % (priority, enabled, name) def print_list(self, title, filter_list): - """Print a list.""" if filter_list: print title @@ -109,7 +209,7 @@ class InfoFrameFilter(gdb.Command): cp.frame_filters) for objfile in gdb.objfiles(): - self.print_list(" objfile %s frame-filters:" % objfile.filename, + self.print_list("objfile %s frame-filters:" % objfile.filename, objfile.frame_filters) def do_enable_frame_filter_1 (frame_filters, name, flag): @@ -120,10 +220,13 @@ def do_enable_frame_filter_1 (frame_filters, name, flag): name: object to select printers flag: True for Enable, False for Disable """ - for ff in frame_filters: - if (hasattr(ff, "name") and _get_name(ff) == name or - hasattr(ff, "__name__") and ff.__name__ == name): - _set_enabled(ff,flag) + try: + ff = frame_filters[name] + except KeyError: + msg = "frame-filter '" + str(name) + "' not found." + raise gdb.GdbError(msg) + + _set_enabled(ff, flag) def do_enable_frame_filter (command_tuple, flag): """Internal worker for enabling/disabling frame-filters.""" @@ -131,18 +234,8 @@ def do_enable_frame_filter (command_tuple, flag): list_op = command_tuple[0] frame_filter = command_tuple[1] - if list_op == "all" or list_op == "global": - do_enable_frame_filter_1(gdb.frame_filters, - frame_filter, flag) - if list_op == "all" or list_op == "progspace": - cp = gdb.current_progspace() - do_enable_frame_filter_1(cp.frame_filters, - frame_filter, flag) - if list_op == "all" or list_op == "objfile": - for objfile in gdb.objfiles(): - if object_list == objfile.filename: - do_enable_frame_filter_1(objfile.frame_filters, - frame_filter, flag) + op_list = _return_list(list_op) + do_enable_frame_filter_1(op_list, frame_filter, flag) class FilterPrefixCmd (gdb.Command): def __init__ (self): @@ -155,11 +248,11 @@ class EnableFrameFilter (gdb.Command): Usage: set python frame-filter enable [list] [name] - LIST is the name of the frame-filter list to operate on, or 'all' - to operate on all frame-filter lists. Named lists are: "global" - for the global frame-filter list, "progspace" for the program - space's file frame-filter list, and "objfile" for the objfiles - within that program space frame-filter list. + LIST is the name of the frame-filter list to operate. Named lists + are: "global" for the global frame-filter list, "progspace" for + the program space's file frame-filter list. If either of these + two are not specified, the list name is assumed to be the name of + the object-file name. NAME matches the name of the frame-filter to operate on. """ @@ -179,11 +272,11 @@ class DisableFrameFilter (gdb.Command): Usage: set python frame-filter disable [list] [name] - LIST is the name of the frame-filter list to operate on, or 'all' - to operate on all frame-filter lists. Named lists are: "global" - for the global frame-filter list, "progspace" for the program - space's file frame-filter list, and "objfile" for the objfiles - within that program space frame-filter list. + LIST is the name of the frame-filter list to operate. Named lists + are: "global" for the global frame-filter list, "progspace" for + the program space's file frame-filter list. If either of these + two are not specified, the list name is assumed to be the name of + the object-file name. NAME matches the name of the frame-filter to operate on. """ @@ -202,11 +295,11 @@ class SetFrameFilterPriority (gdb.Command): Usage: set python frame-filter priority [list] [name] [priority] - LIST is the name of the frame-filter list to operate on, or 'all' - to operate on all frame-filter lists. Named lists are: "global" - for the global frame-filter list, "progspace" for the program - space's file frame-filter list, and "objfile" for the objfiles - within that program space frame-filter list. + LIST is the name of the frame-filter list to operate. Named lists + are: "global" for the global frame-filter list, "progspace" for + the program space's file frame-filter list. If either of these + two are not specified, the list name is assumed to be the name of + the object-file name. NAME matches the name of the frame-filter to operate on. @@ -218,7 +311,6 @@ class SetFrameFilterPriority (gdb.Command): "frame-filter priority", gdb.COMMAND_DATA, gdb.COMPLETE_COMMAND) - def _parse_pri_arg (self, arg): argv = gdb.string_to_argv(arg); argc = len(argv) @@ -240,11 +332,13 @@ class SetFrameFilterPriority (gdb.Command): name: object to select printers. priority: Priority of filter. """ + try: + ff = frame_filters[name] + except KeyError: + msg = "frame-filter '" + str(name) + "' not found." + raise gdb.GdbError(msg) - for ff in frame_filters: - if (hasattr(ff, "name") and _get_name(ff) == name or - hasattr(ff, "__name__") and ff.__name__ == name): - _set_priority(ff, priority) + _set_priority(ff, priority) def _set_filter_priority (self,command_tuple): """Internal worker for setting priority of frame-filters.""" @@ -253,18 +347,9 @@ class SetFrameFilterPriority (gdb.Command): frame_filter = command_tuple[1] priority = command_tuple [2] - if list_op == "all" or list_op == "global": - self._set_filter_priority_1(gdb.frame_filters, - frame_filter, priority) - if list_op == "all" or list_op == "progspace": - cp = gdb.current_progspace() - self._set_filter_priority_filter_1(cp.frame_filters, - frame_filter, priority) - if list_op == "all" or list_op == "objfile": - for objfile in gdb.objfiles(): - if object_list == objfile.filename: - self._set_filter_priority_1(objfile.frame_filters, - frame_filter, priority) + op_list = _return_list (list_op) + + self._set_filter_priority_1(op_list, frame_filter, priority) def invoke(self, arg, from_tty): """GDB calls this to perform the command.""" diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index fec12f3..2991364 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -748,12 +748,26 @@ apply_frame_filter (struct frame_info *frame, int print_level, int print_result = 0; struct value_print_options opts; int success = 0; + PyObject *filter_list; + PyObject *sort_func; + PyObject *sort; + PyObject *module; 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()) + { + gdbpy_print_stack (); + return 0; + } + /* Build the filter list ordered by priority. */ /* Find the constructor. */ filter = find_frame_filter (frame_obj, count); diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c index f06226c..38ed010 100644 --- a/gdb/python/py-objfile.c +++ b/gdb/python/py-objfile.c @@ -81,7 +81,7 @@ objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords) return NULL; } - self->frame_filters = PyList_New (0); + self->frame_filters = PyDict_New (); if (!self->frame_filters) { Py_DECREF (self->printers); @@ -153,10 +153,10 @@ objfpy_set_frame_filters (PyObject *o, PyObject *filters, void *ignore) return -1; } - if (! PyList_Check (filters)) + if (! PyDict_Check (filters)) { PyErr_SetString (PyExc_TypeError, - _("The frame_filters attribute must be a list.")); + _("The frame_filters attribute must be a dictionary.")); return -1; } @@ -223,7 +223,7 @@ objfile_to_objfile_object (struct objfile *objfile) return NULL; } - object->frame_filters = PyList_New (0); + object->frame_filters = PyDict_New (); if (!object->frame_filters) { Py_DECREF (object->printers); diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c index d4c03b4..0a3571c 100644 --- a/gdb/python/py-progspace.c +++ b/gdb/python/py-progspace.c @@ -90,7 +90,7 @@ pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords) return NULL; } - self->frame_filters = PyList_New (0); + self->frame_filters = PyDict_New (); if (!self->frame_filters) { Py_DECREF (self->printers); @@ -162,10 +162,10 @@ pspy_set_frame_filters (PyObject *o, PyObject *frame, void *ignore) return -1; } - if (! PyList_Check (frame)) + if (! PyDict_Check (frame)) { PyErr_SetString (PyExc_TypeError, - "the frame filter attribute must be a list"); + "the frame filter attribute must be a dictionary"); return -1; } @@ -220,7 +220,7 @@ pspace_to_pspace_object (struct program_space *pspace) return NULL; } - object->frame_filters = PyList_New (0); + object->frame_filters = PyDict_New (); if (!object->frame_filters) { Py_DECREF (object->printers); diff --git a/gdb/python/python.c b/gdb/python/python.c index 97258b5..0f23899 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1293,7 +1293,7 @@ message == an error message without a stack will be printed."), PyRun_SimpleString ("import gdb"); PyRun_SimpleString ("gdb.pretty_printers = []"); - PyRun_SimpleString ("gdb.frame_filters = []"); + PyRun_SimpleString ("gdb.frame_filters = {}"); gdbpy_to_string_cst = PyString_FromString ("to_string"); gdbpy_children_cst = PyString_FromString ("children"); hooks/post-receive -- Repository for Project Archer.
reply other threads:[~2012-06-21 11:11 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=20120621111128.6178.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).