| Index: gdb/python/lib/gdb/command/frame_filters.py
|
| diff --git a/gdb/python/lib/gdb/command/frame_filters.py b/gdb/python/lib/gdb/command/frame_filters.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b04f47791622f262f7504fadc50750d69b9c1701
|
| --- /dev/null
|
| +++ b/gdb/python/lib/gdb/command/frame_filters.py
|
| @@ -0,0 +1,467 @@
|
| +# Frame-filter commands.
|
| +# Copyright (C) 2013 Free Software Foundation, Inc.
|
| +
|
| +# This program is free software; you can redistribute it and/or modify
|
| +# it under the terms of the GNU General Public License as published by
|
| +# the Free Software Foundation; either version 3 of the License, or
|
| +# (at your option) any later version.
|
| +#
|
| +# This program is distributed in the hope that it will be useful,
|
| +# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| +# GNU General Public License for more details.
|
| +#
|
| +# You should have received a copy of the GNU General Public License
|
| +# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| +
|
| +"""GDB commands for working with frame-filters."""
|
| +
|
| +import sys
|
| +import gdb
|
| +import copy
|
| +from gdb.FrameIterator import FrameIterator
|
| +from gdb.FrameDecorator import FrameDecorator
|
| +import gdb.frames
|
| +import itertools
|
| +
|
| +# GDB Commands.
|
| +class SetFilterPrefixCmd(gdb.Command):
|
| + """Prefix command for 'set' frame-filter related operations."""
|
| +
|
| + def __init__(self):
|
| + super(SetFilterPrefixCmd, self).__init__("set frame-filter",
|
| + gdb.COMMAND_OBSCURE,
|
| + gdb.COMPLETE_NONE, True)
|
| +
|
| +class ShowFilterPrefixCmd(gdb.Command):
|
| + """Prefix command for 'show' frame-filter related operations."""
|
| + def __init__(self):
|
| + super(ShowFilterPrefixCmd, self).__init__("show frame-filter",
|
| + gdb.COMMAND_OBSCURE,
|
| + gdb.COMPLETE_NONE, True)
|
| +class InfoFrameFilter(gdb.Command):
|
| + """List all registered Python frame-filters.
|
| +
|
| + Usage: info frame-filters
|
| + """
|
| +
|
| + def __init__(self):
|
| + super(InfoFrameFilter, self).__init__("info frame-filter",
|
| + gdb.COMMAND_DATA)
|
| + @staticmethod
|
| + def enabled_string(state):
|
| + """Return "Yes" if filter is enabled, otherwise "No"."""
|
| + if state:
|
| + return "Yes"
|
| + else:
|
| + return "No"
|
| +
|
| + def list_frame_filters(self, frame_filters):
|
| + """ Internal worker function to list and print frame filters
|
| + in a dictionary.
|
| +
|
| + Arguments:
|
| + frame_filters: The name of the dictionary, as
|
| + specified by GDB user commands.
|
| + """
|
| +
|
| + sorted_frame_filters = sorted(frame_filters.items(),
|
| + key=lambda i: gdb.frames.get_priority(i[1]),
|
| + reverse=True)
|
| +
|
| + if len(sorted_frame_filters) == 0:
|
| + print(" No frame filters registered.")
|
| + else:
|
| + print(" Priority Enabled Name")
|
| + for frame_filter in sorted_frame_filters:
|
| + name = frame_filter[0]
|
| + try:
|
| + priority = '{:<8}'.format(
|
| + str(gdb.frames.get_priority(frame_filter[1])))
|
| + enabled = '{:<7}'.format(
|
| + self.enabled_string(gdb.frames.get_enabled(frame_filter[1])))
|
| + except Exception:
|
| + e = sys.exc_info()[1]
|
| + print(" Error printing filter '"+name+"': "+str(e))
|
| + else:
|
| + print(" %s %s %s" % (priority, enabled, name))
|
| +
|
| + def print_list(self, title, filter_list, blank_line):
|
| + print(title)
|
| + self.list_frame_filters(filter_list)
|
| + if blank_line:
|
| + print("")
|
| +
|
| + def invoke(self, arg, from_tty):
|
| + self.print_list("global frame-filters:", gdb.frame_filters, True)
|
| +
|
| + cp = gdb.current_progspace()
|
| + self.print_list("progspace %s frame-filters:" % cp.filename,
|
| + cp.frame_filters, True)
|
| +
|
| + for objfile in gdb.objfiles():
|
| + self.print_list("objfile %s frame-filters:" % objfile.filename,
|
| + objfile.frame_filters, False)
|
| +
|
| +# Internal enable/disable functions.
|
| +
|
| +def _enable_parse_arg(cmd_name, arg):
|
| + """ Internal worker function to take an argument from
|
| + enable/disable and return a tuple of arguments.
|
| +
|
| + Arguments:
|
| + cmd_name: Name of the command invoking this function.
|
| + args: The argument as a string.
|
| +
|
| + Returns:
|
| + A tuple containing the dictionary, and the argument, or just
|
| + the dictionary in the case of "all".
|
| + """
|
| +
|
| + argv = gdb.string_to_argv(arg);
|
| + argc = len(argv)
|
| + if argv[0] == "all" and argc > 1:
|
| + raise gdb.GdbError(cmd_name + ": with 'all' " \
|
| + "you may not specify a filter.")
|
| + else:
|
| + if argv[0] != "all" and argc != 2:
|
| + raise gdb.GdbError(cmd_name + " takes exactly two arguments.")
|
| +
|
| + return argv
|
| +
|
| +def _do_enable_frame_filter(command_tuple, flag):
|
| + """Worker for enabling/disabling frame_filters.
|
| +
|
| + Arguments:
|
| + command_type: A tuple with the first element being the
|
| + frame filter dictionary, and the second being
|
| + the frame filter name.
|
| + flag: True for Enable, False for Disable.
|
| + """
|
| +
|
| + list_op = command_tuple[0]
|
| + op_list = gdb.frames.return_list(list_op)
|
| +
|
| + if list_op == "all":
|
| + for item in op_list:
|
| + gdb.frames.set_enabled(item, flag)
|
| + else:
|
| + frame_filter = command_tuple[1]
|
| + try:
|
| + ff = op_list[frame_filter]
|
| + except KeyError:
|
| + msg = "frame-filter '" + str(name) + "' not found."
|
| + raise gdb.GdbError(msg)
|
| +
|
| + gdb.frames.set_enabled(ff, flag)
|
| +
|
| +def _complete_frame_filter_list(text, word, all_flag):
|
| + """Worker for frame filter dictionary name completion.
|
| +
|
| + Arguments:
|
| + text: The full text of the command line.
|
| + word: The most recent word of the command line.
|
| + all_flag: Whether to include the word "all" in completion.
|
| +
|
| + Returns:
|
| + A list of suggested frame filter dictionary name completions
|
| + from text/word analysis. This list can be empty when there
|
| + are no suggestions for completion.
|
| + """
|
| + if all_flag == True:
|
| + filter_locations = ["all", "global", "progspace"]
|
| + else:
|
| + filter_locations = ["global", "progspace"]
|
| + for objfile in gdb.objfiles():
|
| + filter_locations.append(objfile.filename)
|
| +
|
| + # If the user just asked for completions with no completion
|
| + # hints, just return all the frame filter dictionaries we know
|
| + # about.
|
| + if (text == ""):
|
| + return filter_locations
|
| +
|
| + # Otherwise filter on what we know.
|
| + flist = filter(lambda x,y=text:x.startswith(y), filter_locations)
|
| +
|
| + # If we only have one completion, complete it and return it.
|
| + if len(flist) == 1:
|
| + flist[0] = flist[0][len(text)-len(word):]
|
| +
|
| + # Otherwise, return an empty list, or a list of frame filter
|
| + # dictionaries that the previous filter operation returned.
|
| + return flist
|
| +
|
| +def _complete_frame_filter_name(word, printer_dict):
|
| + """Worker for frame filter name completion.
|
| +
|
| + Arguments:
|
| +
|
| + word: The most recent word of the command line.
|
| +
|
| + printer_dict: The frame filter dictionary to search for frame
|
| + filter name completions.
|
| +
|
| + Returns: A list of suggested frame filter name completions
|
| + from word analysis of the frame filter dictionary. This list
|
| + can be empty when there are no suggestions for completion.
|
| + """
|
| +
|
| + printer_keys = printer_dict.keys()
|
| + if (word == ""):
|
| + return printer_keys
|
| +
|
| + flist = filter(lambda x,y=word:x.startswith(y), printer_keys)
|
| + return flist
|
| +
|
| +class EnableFrameFilter(gdb.Command):
|
| + """GDB command to disable the specified frame-filter.
|
| +
|
| + Usage: enable frame-filter enable DICTIONARY [NAME]
|
| +
|
| + DICTIONARY is the name of the frame filter dictionary on which to
|
| + operate. If dictionary is set to "all", perform operations on all
|
| + dictionaries. Named dictionaries are: "global" for the global
|
| + frame filter dictionary, "progspace" for the program space's frame
|
| + filter dictionary. If either all, or the two named dictionaries
|
| + are not specified, the dictionary name is assumed to be the name
|
| + of the object-file name.
|
| +
|
| + NAME matches the name of the frame-filter to operate on. If
|
| + DICTIONARY is "all", NAME is ignored.
|
| + """
|
| + def __init__(self):
|
| + super(EnableFrameFilter, self).__init__("enable frame-filter",
|
| + gdb.COMMAND_DATA)
|
| + def complete(self, text, word):
|
| + """Completion function for both frame filter dictionary, and
|
| + frame filter name."""
|
| + if text.count(" ") == 0:
|
| + return _complete_frame_filter_list(text, word, True)
|
| + else:
|
| + printer_list = gdb.frames.return_list(text.split()[0].rstrip())
|
| + return _complete_frame_filter_name(word, printer_list)
|
| +
|
| + def invoke(self, arg, from_tty):
|
| + command_tuple = _enable_parse_arg("enable frame-filter", arg)
|
| + _do_enable_frame_filter(command_tuple, True)
|
| +
|
| +
|
| +class DisableFrameFilter(gdb.Command):
|
| + """GDB command to disable the specified frame-filter.
|
| +
|
| + Usage: disable frame-filter disable DICTIONARY [NAME]
|
| +
|
| + DICTIONARY is the name of the frame filter dictionary on which to
|
| + operate. If dictionary is set to "all", perform operations on all
|
| + dictionaries. Named dictionaries are: "global" for the global
|
| + frame filter dictionary, "progspace" for the program space's frame
|
| + filter dictionary. If either all, or the two named dictionaries
|
| + are not specified, the dictionary name is assumed to be the name
|
| + of the object-file name.
|
| +
|
| + NAME matches the name of the frame-filter to operate on. If
|
| + DICTIONARY is "all", NAME is ignored.
|
| + """
|
| + def __init__(self):
|
| + super(DisableFrameFilter, self).__init__("disable frame-filter",
|
| + gdb.COMMAND_DATA)
|
| +
|
| + def complete(self, text, word):
|
| + """Completion function for both frame filter dictionary, and
|
| + frame filter name."""
|
| + if text.count(" ") == 0:
|
| + return _complete_frame_filter_list(text, word, True)
|
| + else:
|
| + printer_list = gdb.frames.return_list(text.split()[0].rstrip())
|
| + return _complete_frame_filter_name(word, printer_list)
|
| +
|
| + def invoke(self, arg, from_tty):
|
| + command_tuple = _enable_parse_arg("disable frame-filter", arg)
|
| + _do_enable_frame_filter(command_tuple, False)
|
| +
|
| +class SetFrameFilterPriority(gdb.Command):
|
| + """GDB command to set the priority of the specified frame-filter.
|
| +
|
| + Usage: set frame-filter priority DICTIONARY NAME PRIORITY
|
| +
|
| + DICTIONARY is the name of the frame filter dictionary on which to
|
| + operate. Named dictionaries are: "global" for the global frame
|
| + filter dictionary, "progspace" for the program space's framefilter
|
| + dictionary. If either of these two are not specified, the
|
| + dictionary name is assumed to be the name of the object-file name.
|
| +
|
| + NAME matches the name of the frame filter to operate on.
|
| +
|
| + PRIORITY is the an integer to assign the new priority to the frame
|
| + filter.
|
| + """
|
| +
|
| + def __init__(self):
|
| + super(SetFrameFilterPriority, self).__init__("set frame-filter " \
|
| + "priority",
|
| + gdb.COMMAND_DATA)
|
| +
|
| + def _parse_pri_arg(self, arg):
|
| + """Internal worker to parse a priority from a tuple.
|
| +
|
| + Arguments:
|
| + arg: Tuple which contains the arguments from the command.
|
| +
|
| + Returns:
|
| + A tuple containing the dictionary, name and priority from
|
| + the arguments.
|
| +
|
| + Raises:
|
| + gdb.GdbError: An error parsing the arguments.
|
| + """
|
| +
|
| + argv = gdb.string_to_argv(arg);
|
| + argc = len(argv)
|
| + if argc != 3:
|
| + print("set frame-filter priority " \
|
| + "takes exactly three arguments.")
|
| + return None
|
| +
|
| + return argv
|
| +
|
| + def _set_filter_priority(self, command_tuple):
|
| + """Internal worker for setting priority of frame-filters, by
|
| + parsing a tuple and calling _set_priority with the parsed
|
| + tuple.
|
| +
|
| + Arguments:
|
| + command_tuple: Tuple which contains the arguments from the
|
| + command.
|
| + """
|
| +
|
| + list_op = command_tuple[0]
|
| + frame_filter = command_tuple[1]
|
| +
|
| + # GDB returns arguments as a string, so convert priority to
|
| + # a number.
|
| + priority = int(command_tuple[2])
|
| +
|
| + op_list = gdb.frames.return_list(list_op)
|
| +
|
| + try:
|
| + ff = op_list[frame_filter]
|
| + except KeyError:
|
| + msg = "frame-filter '" + str(name) + "' not found."
|
| + raise gdb.GdbError(msg)
|
| +
|
| + gdb.frames.set_priority(ff, priority)
|
| +
|
| + def complete(self, text, word):
|
| + """Completion function for both frame filter dictionary, and
|
| + frame filter name."""
|
| + if text.count(" ") == 0:
|
| + return _complete_frame_filter_list(text, word, False)
|
| + else:
|
| + printer_list = gdb.frames.return_list(text.split()[0].rstrip())
|
| + return _complete_frame_filter_name(word, printer_list)
|
| +
|
| + def invoke(self, arg, from_tty):
|
| + command_tuple = self._parse_pri_arg(arg)
|
| + if command_tuple != None:
|
| + self._set_filter_priority(command_tuple)
|
| +
|
| +class ShowFrameFilterPriority(gdb.Command):
|
| + """GDB command to show the priority of the specified frame-filter.
|
| +
|
| + Usage: show frame-filter priority DICTIONARY NAME
|
| +
|
| + DICTIONARY is the name of the frame filter dictionary on which to
|
| + operate. Named dictionaries are: "global" for the global frame
|
| + filter dictionary, "progspace" for the program space's framefilter
|
| + dictionary. If either of these two are not specified, the
|
| + dictionary name is assumed to be the name of the object-file name.
|
| +
|
| + NAME matches the name of the frame-filter to operate on.
|
| + """
|
| +
|
| + def __init__(self):
|
| + super(ShowFrameFilterPriority, self).__init__("show frame-filter " \
|
| + "priority",
|
| + gdb.COMMAND_DATA)
|
| +
|
| + def _parse_pri_arg(self, arg):
|
| + """Internal worker to parse a dictionary and name from a
|
| + tuple.
|
| +
|
| + Arguments:
|
| + arg: Tuple which contains the arguments from the command.
|
| +
|
| + Returns:
|
| + A tuple containing the dictionary, and frame filter name.
|
| +
|
| + Raises:
|
| + gdb.GdbError: An error parsing the arguments.
|
| + """
|
| +
|
| + argv = gdb.string_to_argv(arg);
|
| + argc = len(argv)
|
| + if argc != 2:
|
| + print("show frame-filter priority " \
|
| + "takes exactly two arguments.")
|
| + return None
|
| +
|
| + return argv
|
| +
|
| + def get_filter_priority(self, frame_filters, name):
|
| + """Worker for retrieving the priority of frame_filters.
|
| +
|
| + Arguments:
|
| + frame_filters: Name of frame filter dictionary.
|
| + name: object to select printers.
|
| +
|
| + Returns:
|
| + The priority of the frame filter.
|
| +
|
| + Raises:
|
| + gdb.GdbError: A frame filter cannot be found.
|
| + """
|
| +
|
| + op_list = gdb.frames.return_list(frame_filters)
|
| +
|
| + try:
|
| + ff = op_list[name]
|
| + except KeyError:
|
| + msg = "frame-filter '" + str(name) + "' not found."
|
| + raise gdb.GdbError(msg)
|
| +
|
| + return gdb.frames.get_priority(ff)
|
| +
|
| + def complete(self, text, word):
|
| + """Completion function for both frame filter dictionary, and
|
| + frame filter name."""
|
| +
|
| + if text.count(" ") == 0:
|
| + return _complete_frame_filter_list(text, word, False)
|
| + else:
|
| + printer_list = frame._return_list(text.split()[0].rstrip())
|
| + return _complete_frame_filter_name(word, printer_list)
|
| +
|
| + def invoke(self, arg, from_tty):
|
| + command_tuple = self._parse_pri_arg(arg)
|
| + if command_tuple == None:
|
| + return
|
| + filter_name = command_tuple[1]
|
| + list_name = command_tuple[0]
|
| + try:
|
| + priority = self.get_filter_priority(list_name, filter_name);
|
| + except Exception:
|
| + e = sys.exc_info()[1]
|
| + print("Error printing filter priority for '"+name+"':"+str(e))
|
| + else:
|
| + print("Priority of filter '" + filter_name + "' in list '" \
|
| + + list_name + "' is: " + str(priority))
|
| +
|
| +# Register commands
|
| +SetFilterPrefixCmd()
|
| +ShowFilterPrefixCmd()
|
| +InfoFrameFilter()
|
| +EnableFrameFilter()
|
| +DisableFrameFilter()
|
| +SetFrameFilterPriority()
|
| +ShowFrameFilterPriority()
|
|
|