GDB (API)
/home/stan/gdb/linux/gdb/data-directory/python/gdb/command/frame_filters.py
Go to the documentation of this file.
00001 # Frame-filter commands.
00002 # Copyright (C) 2013 Free Software Foundation, Inc.
00003 
00004 # This program is free software; you can redistribute it and/or modify
00005 # it under the terms of the GNU General Public License as published by
00006 # the Free Software Foundation; either version 3 of the License, or
00007 # (at your option) any later version.
00008 #
00009 # This program is distributed in the hope that it will be useful,
00010 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 # GNU General Public License for more details.
00013 #
00014 # You should have received a copy of the GNU General Public License
00015 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 """GDB commands for working with frame-filters."""
00018 
00019 import sys
00020 import gdb
00021 import copy
00022 from gdb.FrameIterator import FrameIterator
00023 from gdb.FrameDecorator import FrameDecorator
00024 import gdb.frames
00025 import itertools
00026 
00027 # GDB Commands.
00028 class SetFilterPrefixCmd(gdb.Command):
00029     """Prefix command for 'set' frame-filter related operations."""
00030 
00031     def __init__(self):
00032         super(SetFilterPrefixCmd, self).__init__("set frame-filter",
00033                                                  gdb.COMMAND_OBSCURE,
00034                                                  gdb.COMPLETE_NONE, True)
00035 
00036 class ShowFilterPrefixCmd(gdb.Command):
00037     """Prefix command for 'show' frame-filter related operations."""
00038     def __init__(self):
00039         super(ShowFilterPrefixCmd, self).__init__("show frame-filter",
00040                                                   gdb.COMMAND_OBSCURE,
00041                                                   gdb.COMPLETE_NONE, True)
00042 class InfoFrameFilter(gdb.Command):
00043     """List all registered Python frame-filters.
00044 
00045     Usage: info frame-filters
00046     """
00047 
00048     def __init__(self):
00049         super(InfoFrameFilter, self).__init__("info frame-filter",
00050                                               gdb.COMMAND_DATA)
00051     @staticmethod
00052     def enabled_string(state):
00053         """Return "Yes" if filter is enabled, otherwise "No"."""
00054         if state:
00055             return "Yes"
00056         else:
00057             return "No"
00058 
00059     def list_frame_filters(self, frame_filters):
00060         """ Internal worker function to list and print frame filters
00061         in a dictionary.
00062 
00063         Arguments:
00064            frame_filters: The name of the dictionary, as
00065            specified by GDB user commands.
00066         """
00067 
00068         sorted_frame_filters = sorted(frame_filters.items(),
00069                                       key=lambda i: gdb.frames.get_priority(i[1]),
00070                                       reverse=True)
00071 
00072         if len(sorted_frame_filters) == 0:
00073             print("  No frame filters registered.")
00074         else:
00075             print("  Priority  Enabled  Name")
00076             for frame_filter in sorted_frame_filters:
00077                 name = frame_filter[0]
00078                 try:
00079                     priority = '{:<8}'.format(
00080                         str(gdb.frames.get_priority(frame_filter[1])))
00081                     enabled = '{:<7}'.format(
00082                         self.enabled_string(gdb.frames.get_enabled(frame_filter[1])))
00083                 except Exception:
00084                     e = sys.exc_info()[1]
00085                     print("  Error printing filter '"+name+"': "+str(e))
00086                 else:
00087                     print("  %s  %s  %s" % (priority, enabled, name))
00088 
00089     def print_list(self, title, filter_list, blank_line):
00090         print(title)
00091         self.list_frame_filters(filter_list)
00092         if blank_line:
00093             print("")
00094 
00095     def invoke(self, arg, from_tty):
00096         self.print_list("global frame-filters:", gdb.frame_filters, True)
00097 
00098         cp = gdb.current_progspace()
00099         self.print_list("progspace %s frame-filters:" % cp.filename,
00100                         cp.frame_filters, True)
00101 
00102         for objfile in gdb.objfiles():
00103             self.print_list("objfile %s frame-filters:" % objfile.filename,
00104                             objfile.frame_filters, False)
00105 
00106 # Internal enable/disable functions.
00107 
00108 def _enable_parse_arg(cmd_name, arg):
00109     """ Internal worker function to take an argument from
00110     enable/disable and return a tuple of arguments.
00111 
00112     Arguments:
00113         cmd_name: Name of the command invoking this function.
00114         args: The argument as a string.
00115 
00116     Returns:
00117         A tuple containing the dictionary, and the argument, or just
00118         the dictionary in the case of "all".
00119     """
00120 
00121     argv = gdb.string_to_argv(arg);
00122     argc = len(argv)
00123     if argv[0] == "all" and argc > 1:
00124         raise gdb.GdbError(cmd_name + ": with 'all' " \
00125                           "you may not specify a filter.")
00126     else:
00127         if argv[0] != "all" and argc != 2:
00128             raise gdb.GdbError(cmd_name + " takes exactly two arguments.")
00129 
00130     return argv
00131 
00132 def _do_enable_frame_filter(command_tuple, flag):
00133     """Worker for enabling/disabling frame_filters.
00134 
00135     Arguments:
00136         command_type: A tuple with the first element being the
00137                       frame filter dictionary, and the second being
00138                       the frame filter name.
00139         flag: True for Enable, False for Disable.
00140     """
00141 
00142     list_op = command_tuple[0]
00143     op_list = gdb.frames.return_list(list_op)
00144 
00145     if list_op == "all":
00146         for item in op_list:
00147             gdb.frames.set_enabled(item, flag)
00148     else:
00149         frame_filter = command_tuple[1]
00150         try:
00151             ff = op_list[frame_filter]
00152         except KeyError:
00153             msg = "frame-filter '" + str(name) + "' not found."
00154             raise gdb.GdbError(msg)
00155 
00156         gdb.frames.set_enabled(ff, flag)
00157 
00158 def _complete_frame_filter_list(text, word, all_flag):
00159     """Worker for frame filter dictionary name completion.
00160 
00161     Arguments:
00162         text: The full text of the command line.
00163         word: The most recent word of the command line.
00164         all_flag: Whether to include the word "all" in completion.
00165 
00166     Returns:
00167         A list of suggested frame filter dictionary name completions
00168         from text/word analysis.  This list can be empty when there
00169         are no suggestions for completion.
00170         """
00171     if all_flag == True:
00172         filter_locations = ["all", "global", "progspace"]
00173     else:
00174         filter_locations = ["global", "progspace"]
00175     for objfile in gdb.objfiles():
00176         filter_locations.append(objfile.filename)
00177 
00178     # If the user just asked for completions with no completion
00179     # hints, just return all the frame filter dictionaries we know
00180     # about.
00181     if (text == ""):
00182         return filter_locations
00183 
00184     # Otherwise filter on what we know.
00185     flist = filter(lambda x,y=text:x.startswith(y), filter_locations)
00186 
00187     # If we only have one completion, complete it and return it.
00188     if len(flist) == 1:
00189         flist[0] = flist[0][len(text)-len(word):]
00190 
00191     # Otherwise, return an empty list, or a list of frame filter
00192     # dictionaries that the previous filter operation returned.
00193     return flist
00194 
00195 def _complete_frame_filter_name(word, printer_dict):
00196     """Worker for frame filter name completion.
00197 
00198     Arguments:
00199 
00200         word: The most recent word of the command line.
00201 
00202         printer_dict: The frame filter dictionary to search for frame
00203         filter name completions.
00204 
00205         Returns: A list of suggested frame filter name completions
00206         from word analysis of the frame filter dictionary.  This list
00207         can be empty when there are no suggestions for completion.
00208     """
00209 
00210     printer_keys = printer_dict.keys()
00211     if (word == ""):
00212         return printer_keys
00213 
00214     flist = filter(lambda x,y=word:x.startswith(y), printer_keys)
00215     return flist
00216 
00217 class EnableFrameFilter(gdb.Command):
00218     """GDB command to disable the specified frame-filter.
00219 
00220     Usage: enable frame-filter enable DICTIONARY [NAME]
00221 
00222     DICTIONARY is the name of the frame filter dictionary on which to
00223     operate.  If dictionary is set to "all", perform operations on all
00224     dictionaries.  Named dictionaries are: "global" for the global
00225     frame filter dictionary, "progspace" for the program space's frame
00226     filter dictionary.  If either all, or the two named dictionaries
00227     are not specified, the dictionary name is assumed to be the name
00228     of the object-file name.
00229 
00230     NAME matches the name of the frame-filter to operate on.  If
00231     DICTIONARY is "all", NAME is ignored.
00232     """
00233     def __init__(self):
00234         super(EnableFrameFilter, self).__init__("enable frame-filter",
00235                                                  gdb.COMMAND_DATA)
00236     def complete(self, text, word):
00237         """Completion function for both frame filter dictionary, and
00238         frame filter name."""
00239         if text.count(" ") == 0:
00240             return _complete_frame_filter_list(text, word, True)
00241         else:
00242             printer_list = gdb.frames.return_list(text.split()[0].rstrip())
00243             return _complete_frame_filter_name(word, printer_list)
00244 
00245     def invoke(self, arg, from_tty):
00246         command_tuple = _enable_parse_arg("enable frame-filter", arg)
00247         _do_enable_frame_filter(command_tuple, True)
00248 
00249 
00250 class DisableFrameFilter(gdb.Command):
00251     """GDB command to disable the specified frame-filter.
00252 
00253     Usage: disable frame-filter disable DICTIONARY [NAME]
00254 
00255     DICTIONARY is the name of the frame filter dictionary on which to
00256     operate.  If dictionary is set to "all", perform operations on all
00257     dictionaries.  Named dictionaries are: "global" for the global
00258     frame filter dictionary, "progspace" for the program space's frame
00259     filter dictionary.  If either all, or the two named dictionaries
00260     are not specified, the dictionary name is assumed to be the name
00261     of the object-file name.
00262 
00263     NAME matches the name of the frame-filter to operate on.  If
00264     DICTIONARY is "all", NAME is ignored.
00265     """
00266     def __init__(self):
00267         super(DisableFrameFilter, self).__init__("disable frame-filter",
00268                                                   gdb.COMMAND_DATA)
00269 
00270     def complete(self, text, word):
00271         """Completion function for both frame filter dictionary, and
00272         frame filter name."""
00273         if text.count(" ") == 0:
00274             return _complete_frame_filter_list(text, word, True)
00275         else:
00276             printer_list = gdb.frames.return_list(text.split()[0].rstrip())
00277             return _complete_frame_filter_name(word, printer_list)
00278 
00279     def invoke(self, arg, from_tty):
00280         command_tuple = _enable_parse_arg("disable frame-filter", arg)
00281         _do_enable_frame_filter(command_tuple, False)
00282 
00283 class SetFrameFilterPriority(gdb.Command):
00284     """GDB command to set the priority of the specified frame-filter.
00285 
00286     Usage: set frame-filter priority DICTIONARY NAME PRIORITY
00287 
00288     DICTIONARY is the name of the frame filter dictionary on which to
00289     operate.  Named dictionaries are: "global" for the global frame
00290     filter dictionary, "progspace" for the program space's framefilter
00291     dictionary.  If either of these two are not specified, the
00292     dictionary name is assumed to be the name of the object-file name.
00293 
00294     NAME matches the name of the frame filter to operate on.
00295 
00296     PRIORITY is the an integer to assign the new priority to the frame
00297     filter.
00298     """
00299 
00300     def __init__(self):
00301         super(SetFrameFilterPriority, self).__init__("set frame-filter " \
00302                                                      "priority",
00303                                                      gdb.COMMAND_DATA)
00304 
00305     def _parse_pri_arg(self, arg):
00306         """Internal worker to parse a priority from a tuple.
00307 
00308         Arguments:
00309             arg: Tuple which contains the arguments from the command.
00310 
00311         Returns:
00312             A tuple containing the dictionary, name and priority from
00313             the arguments.
00314 
00315         Raises:
00316             gdb.GdbError: An error parsing the arguments.
00317         """
00318 
00319         argv = gdb.string_to_argv(arg);
00320         argc = len(argv)
00321         if argc != 3:
00322             print("set frame-filter priority " \
00323                   "takes exactly three arguments.")
00324             return None
00325 
00326         return argv
00327 
00328     def _set_filter_priority(self, command_tuple):
00329         """Internal worker for setting priority of frame-filters, by
00330         parsing a tuple and calling _set_priority with the parsed
00331         tuple.
00332 
00333         Arguments:
00334             command_tuple: Tuple which contains the arguments from the
00335                            command.
00336         """
00337 
00338         list_op = command_tuple[0]
00339         frame_filter = command_tuple[1]
00340 
00341         # GDB returns arguments as a string, so convert priority to
00342         # a number.
00343         priority = int(command_tuple[2])
00344 
00345         op_list = gdb.frames.return_list(list_op)
00346 
00347         try:
00348             ff = op_list[frame_filter]
00349         except KeyError:
00350             msg = "frame-filter '" + str(name) + "' not found."
00351             raise gdb.GdbError(msg)
00352 
00353         gdb.frames.set_priority(ff, priority)
00354 
00355     def complete(self, text, word):
00356         """Completion function for both frame filter dictionary, and
00357         frame filter name."""
00358         if text.count(" ") == 0:
00359             return _complete_frame_filter_list(text, word, False)
00360         else:
00361             printer_list = gdb.frames.return_list(text.split()[0].rstrip())
00362             return _complete_frame_filter_name(word, printer_list)
00363 
00364     def invoke(self, arg, from_tty):
00365         command_tuple = self._parse_pri_arg(arg)
00366         if command_tuple != None:
00367             self._set_filter_priority(command_tuple)
00368 
00369 class ShowFrameFilterPriority(gdb.Command):
00370     """GDB command to show the priority of the specified frame-filter.
00371 
00372     Usage: show frame-filter priority DICTIONARY NAME
00373 
00374     DICTIONARY is the name of the frame filter dictionary on which to
00375     operate.  Named dictionaries are: "global" for the global frame
00376     filter dictionary, "progspace" for the program space's framefilter
00377     dictionary.  If either of these two are not specified, the
00378     dictionary name is assumed to be the name of the object-file name.
00379 
00380     NAME matches the name of the frame-filter to operate on.
00381     """
00382 
00383     def __init__(self):
00384         super(ShowFrameFilterPriority, self).__init__("show frame-filter " \
00385                                                       "priority",
00386                                                       gdb.COMMAND_DATA)
00387 
00388     def _parse_pri_arg(self, arg):
00389         """Internal worker to parse a dictionary and name from a
00390         tuple.
00391 
00392         Arguments:
00393             arg: Tuple which contains the arguments from the command.
00394 
00395         Returns:
00396             A tuple containing the dictionary,  and frame filter name.
00397 
00398         Raises:
00399             gdb.GdbError: An error parsing the arguments.
00400         """
00401 
00402         argv = gdb.string_to_argv(arg);
00403         argc = len(argv)
00404         if argc != 2:
00405             print("show frame-filter priority " \
00406                   "takes exactly two arguments.")
00407             return None
00408 
00409         return argv
00410 
00411     def get_filter_priority(self, frame_filters, name):
00412         """Worker for retrieving the priority of frame_filters.
00413 
00414         Arguments:
00415             frame_filters: Name of frame filter dictionary.
00416             name: object to select printers.
00417 
00418         Returns:
00419             The priority of the frame filter.
00420 
00421         Raises:
00422             gdb.GdbError: A frame filter cannot be found.
00423         """
00424 
00425         op_list = gdb.frames.return_list(frame_filters)
00426 
00427         try:
00428             ff = op_list[name]
00429         except KeyError:
00430             msg = "frame-filter '" + str(name) + "' not found."
00431             raise gdb.GdbError(msg)
00432 
00433         return gdb.frames.get_priority(ff)
00434 
00435     def complete(self, text, word):
00436         """Completion function for both frame filter dictionary, and
00437         frame filter name."""
00438 
00439         if text.count(" ") == 0:
00440             return _complete_frame_filter_list(text, word, False)
00441         else:
00442             printer_list = frame._return_list(text.split()[0].rstrip())
00443             return _complete_frame_filter_name(word, printer_list)
00444 
00445     def invoke(self, arg, from_tty):
00446         command_tuple = self._parse_pri_arg(arg)
00447         if command_tuple == None:
00448             return
00449         filter_name = command_tuple[1]
00450         list_name = command_tuple[0]
00451         try:
00452             priority = self.get_filter_priority(list_name, filter_name);
00453         except Exception:
00454             e = sys.exc_info()[1]
00455             print("Error printing filter priority for '"+name+"':"+str(e))
00456         else:
00457             print("Priority of filter '" + filter_name + "' in list '" \
00458                 + list_name + "' is: " + str(priority))
00459 
00460 # Register commands
00461 SetFilterPrefixCmd()
00462 ShowFilterPrefixCmd()
00463 InfoFrameFilter()
00464 EnableFrameFilter()
00465 DisableFrameFilter()
00466 SetFrameFilterPriority()
00467 ShowFrameFilterPriority()
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines