]> Git Repo - binutils.git/blob - gdb/python/lib/gdb/command/frame_filters.py
d88cb96501d6adbeee2bf3c6567c09d6081616f6
[binutils.git] / gdb / python / lib / gdb / command / frame_filters.py
1 # Frame-filter commands.
2 # Copyright (C) 2013-2015 Free Software Foundation, Inc.
3
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 """GDB commands for working with frame-filters."""
18
19 import sys
20 import gdb
21 import copy
22 from gdb.FrameIterator import FrameIterator
23 from gdb.FrameDecorator import FrameDecorator
24 import gdb.frames
25 import itertools
26
27 # GDB Commands.
28 class SetFilterPrefixCmd(gdb.Command):
29     """Prefix command for 'set' frame-filter related operations."""
30
31     def __init__(self):
32         super(SetFilterPrefixCmd, self).__init__("set frame-filter",
33                                                  gdb.COMMAND_OBSCURE,
34                                                  gdb.COMPLETE_NONE, True)
35
36 class ShowFilterPrefixCmd(gdb.Command):
37     """Prefix command for 'show' frame-filter related operations."""
38     def __init__(self):
39         super(ShowFilterPrefixCmd, self).__init__("show frame-filter",
40                                                   gdb.COMMAND_OBSCURE,
41                                                   gdb.COMPLETE_NONE, True)
42 class InfoFrameFilter(gdb.Command):
43     """List all registered Python frame-filters.
44
45     Usage: info frame-filters
46     """
47
48     def __init__(self):
49         super(InfoFrameFilter, self).__init__("info frame-filter",
50                                               gdb.COMMAND_DATA)
51     @staticmethod
52     def enabled_string(state):
53         """Return "Yes" if filter is enabled, otherwise "No"."""
54         if state:
55             return "Yes"
56         else:
57             return "No"
58
59     def list_frame_filters(self, frame_filters):
60         """ Internal worker function to list and print frame filters
61         in a dictionary.
62
63         Arguments:
64            frame_filters: The name of the dictionary, as
65            specified by GDB user commands.
66         """
67
68         sorted_frame_filters = sorted(frame_filters.items(),
69                                       key=lambda i: gdb.frames.get_priority(i[1]),
70                                       reverse=True)
71
72         if len(sorted_frame_filters) == 0:
73             print("  No frame filters registered.")
74         else:
75             print("  Priority  Enabled  Name")
76             for frame_filter in sorted_frame_filters:
77                 name = frame_filter[0]
78                 try:
79                     priority = '{:<8}'.format(
80                         str(gdb.frames.get_priority(frame_filter[1])))
81                     enabled = '{:<7}'.format(
82                         self.enabled_string(gdb.frames.get_enabled(frame_filter[1])))
83                 except Exception:
84                     e = sys.exc_info()[1]
85                     print("  Error printing filter '"+name+"': "+str(e))
86                 else:
87                     print("  %s  %s  %s" % (priority, enabled, name))
88
89     def print_list(self, title, filter_list, blank_line):
90         print(title)
91         self.list_frame_filters(filter_list)
92         if blank_line:
93             print("")
94
95     def invoke(self, arg, from_tty):
96         self.print_list("global frame-filters:", gdb.frame_filters, True)
97
98         cp = gdb.current_progspace()
99         self.print_list("progspace %s frame-filters:" % cp.filename,
100                         cp.frame_filters, True)
101
102         for objfile in gdb.objfiles():
103             self.print_list("objfile %s frame-filters:" % objfile.filename,
104                             objfile.frame_filters, False)
105
106 # Internal enable/disable functions.
107
108 def _enable_parse_arg(cmd_name, arg):
109     """ Internal worker function to take an argument from
110     enable/disable and return a tuple of arguments.
111
112     Arguments:
113         cmd_name: Name of the command invoking this function.
114         args: The argument as a string.
115
116     Returns:
117         A tuple containing the dictionary, and the argument, or just
118         the dictionary in the case of "all".
119     """
120
121     argv = gdb.string_to_argv(arg);
122     argc = len(argv)
123     if argv[0] == "all" and argc > 1:
124         raise gdb.GdbError(cmd_name + ": with 'all' " \
125                           "you may not specify a filter.")
126     else:
127         if argv[0] != "all" and argc != 2:
128             raise gdb.GdbError(cmd_name + " takes exactly two arguments.")
129
130     return argv
131
132 def _do_enable_frame_filter(command_tuple, flag):
133     """Worker for enabling/disabling frame_filters.
134
135     Arguments:
136         command_type: A tuple with the first element being the
137                       frame filter dictionary, and the second being
138                       the frame filter name.
139         flag: True for Enable, False for Disable.
140     """
141
142     list_op = command_tuple[0]
143     op_list = gdb.frames.return_list(list_op)
144
145     if list_op == "all":
146         for item in op_list:
147             gdb.frames.set_enabled(item, flag)
148     else:
149         frame_filter = command_tuple[1]
150         try:
151             ff = op_list[frame_filter]
152         except KeyError:
153             msg = "frame-filter '" + str(name) + "' not found."
154             raise gdb.GdbError(msg)
155
156         gdb.frames.set_enabled(ff, flag)
157
158 def _complete_frame_filter_list(text, word, all_flag):
159     """Worker for frame filter dictionary name completion.
160
161     Arguments:
162         text: The full text of the command line.
163         word: The most recent word of the command line.
164         all_flag: Whether to include the word "all" in completion.
165
166     Returns:
167         A list of suggested frame filter dictionary name completions
168         from text/word analysis.  This list can be empty when there
169         are no suggestions for completion.
170         """
171     if all_flag == True:
172         filter_locations = ["all", "global", "progspace"]
173     else:
174         filter_locations = ["global", "progspace"]
175     for objfile in gdb.objfiles():
176         filter_locations.append(objfile.filename)
177
178     # If the user just asked for completions with no completion
179     # hints, just return all the frame filter dictionaries we know
180     # about.
181     if (text == ""):
182         return filter_locations
183
184     # Otherwise filter on what we know.
185     flist = filter(lambda x,y=text:x.startswith(y), filter_locations)
186
187     # If we only have one completion, complete it and return it.
188     if len(flist) == 1:
189         flist[0] = flist[0][len(text)-len(word):]
190
191     # Otherwise, return an empty list, or a list of frame filter
192     # dictionaries that the previous filter operation returned.
193     return flist
194
195 def _complete_frame_filter_name(word, printer_dict):
196     """Worker for frame filter name completion.
197
198     Arguments:
199
200         word: The most recent word of the command line.
201
202         printer_dict: The frame filter dictionary to search for frame
203         filter name completions.
204
205         Returns: A list of suggested frame filter name completions
206         from word analysis of the frame filter dictionary.  This list
207         can be empty when there are no suggestions for completion.
208     """
209
210     printer_keys = printer_dict.keys()
211     if (word == ""):
212         return printer_keys
213
214     flist = filter(lambda x,y=word:x.startswith(y), printer_keys)
215     return flist
216
217 class EnableFrameFilter(gdb.Command):
218     """GDB command to disable the specified frame-filter.
219
220     Usage: enable frame-filter enable DICTIONARY [NAME]
221
222     DICTIONARY is the name of the frame filter dictionary on which to
223     operate.  If dictionary is set to "all", perform operations on all
224     dictionaries.  Named dictionaries are: "global" for the global
225     frame filter dictionary, "progspace" for the program space's frame
226     filter dictionary.  If either all, or the two named dictionaries
227     are not specified, the dictionary name is assumed to be the name
228     of the object-file name.
229
230     NAME matches the name of the frame-filter to operate on.  If
231     DICTIONARY is "all", NAME is ignored.
232     """
233     def __init__(self):
234         super(EnableFrameFilter, self).__init__("enable frame-filter",
235                                                  gdb.COMMAND_DATA)
236     def complete(self, text, word):
237         """Completion function for both frame filter dictionary, and
238         frame filter name."""
239         if text.count(" ") == 0:
240             return _complete_frame_filter_list(text, word, True)
241         else:
242             printer_list = gdb.frames.return_list(text.split()[0].rstrip())
243             return _complete_frame_filter_name(word, printer_list)
244
245     def invoke(self, arg, from_tty):
246         command_tuple = _enable_parse_arg("enable frame-filter", arg)
247         _do_enable_frame_filter(command_tuple, True)
248
249
250 class DisableFrameFilter(gdb.Command):
251     """GDB command to disable the specified frame-filter.
252
253     Usage: disable frame-filter disable DICTIONARY [NAME]
254
255     DICTIONARY is the name of the frame filter dictionary on which to
256     operate.  If dictionary is set to "all", perform operations on all
257     dictionaries.  Named dictionaries are: "global" for the global
258     frame filter dictionary, "progspace" for the program space's frame
259     filter dictionary.  If either all, or the two named dictionaries
260     are not specified, the dictionary name is assumed to be the name
261     of the object-file name.
262
263     NAME matches the name of the frame-filter to operate on.  If
264     DICTIONARY is "all", NAME is ignored.
265     """
266     def __init__(self):
267         super(DisableFrameFilter, self).__init__("disable frame-filter",
268                                                   gdb.COMMAND_DATA)
269
270     def complete(self, text, word):
271         """Completion function for both frame filter dictionary, and
272         frame filter name."""
273         if text.count(" ") == 0:
274             return _complete_frame_filter_list(text, word, True)
275         else:
276             printer_list = gdb.frames.return_list(text.split()[0].rstrip())
277             return _complete_frame_filter_name(word, printer_list)
278
279     def invoke(self, arg, from_tty):
280         command_tuple = _enable_parse_arg("disable frame-filter", arg)
281         _do_enable_frame_filter(command_tuple, False)
282
283 class SetFrameFilterPriority(gdb.Command):
284     """GDB command to set the priority of the specified frame-filter.
285
286     Usage: set frame-filter priority DICTIONARY NAME PRIORITY
287
288     DICTIONARY is the name of the frame filter dictionary on which to
289     operate.  Named dictionaries are: "global" for the global frame
290     filter dictionary, "progspace" for the program space's framefilter
291     dictionary.  If either of these two are not specified, the
292     dictionary name is assumed to be the name of the object-file name.
293
294     NAME matches the name of the frame filter to operate on.
295
296     PRIORITY is the an integer to assign the new priority to the frame
297     filter.
298     """
299
300     def __init__(self):
301         super(SetFrameFilterPriority, self).__init__("set frame-filter " \
302                                                      "priority",
303                                                      gdb.COMMAND_DATA)
304
305     def _parse_pri_arg(self, arg):
306         """Internal worker to parse a priority from a tuple.
307
308         Arguments:
309             arg: Tuple which contains the arguments from the command.
310
311         Returns:
312             A tuple containing the dictionary, name and priority from
313             the arguments.
314
315         Raises:
316             gdb.GdbError: An error parsing the arguments.
317         """
318
319         argv = gdb.string_to_argv(arg);
320         argc = len(argv)
321         if argc != 3:
322             print("set frame-filter priority " \
323                   "takes exactly three arguments.")
324             return None
325
326         return argv
327
328     def _set_filter_priority(self, command_tuple):
329         """Internal worker for setting priority of frame-filters, by
330         parsing a tuple and calling _set_priority with the parsed
331         tuple.
332
333         Arguments:
334             command_tuple: Tuple which contains the arguments from the
335                            command.
336         """
337
338         list_op = command_tuple[0]
339         frame_filter = command_tuple[1]
340
341         # GDB returns arguments as a string, so convert priority to
342         # a number.
343         priority = int(command_tuple[2])
344
345         op_list = gdb.frames.return_list(list_op)
346
347         try:
348             ff = op_list[frame_filter]
349         except KeyError:
350             msg = "frame-filter '" + str(name) + "' not found."
351             raise gdb.GdbError(msg)
352
353         gdb.frames.set_priority(ff, priority)
354
355     def complete(self, text, word):
356         """Completion function for both frame filter dictionary, and
357         frame filter name."""
358         if text.count(" ") == 0:
359             return _complete_frame_filter_list(text, word, False)
360         else:
361             printer_list = gdb.frames.return_list(text.split()[0].rstrip())
362             return _complete_frame_filter_name(word, printer_list)
363
364     def invoke(self, arg, from_tty):
365         command_tuple = self._parse_pri_arg(arg)
366         if command_tuple != None:
367             self._set_filter_priority(command_tuple)
368
369 class ShowFrameFilterPriority(gdb.Command):
370     """GDB command to show the priority of the specified frame-filter.
371
372     Usage: show frame-filter priority DICTIONARY NAME
373
374     DICTIONARY is the name of the frame filter dictionary on which to
375     operate.  Named dictionaries are: "global" for the global frame
376     filter dictionary, "progspace" for the program space's framefilter
377     dictionary.  If either of these two are not specified, the
378     dictionary name is assumed to be the name of the object-file name.
379
380     NAME matches the name of the frame-filter to operate on.
381     """
382
383     def __init__(self):
384         super(ShowFrameFilterPriority, self).__init__("show frame-filter " \
385                                                       "priority",
386                                                       gdb.COMMAND_DATA)
387
388     def _parse_pri_arg(self, arg):
389         """Internal worker to parse a dictionary and name from a
390         tuple.
391
392         Arguments:
393             arg: Tuple which contains the arguments from the command.
394
395         Returns:
396             A tuple containing the dictionary,  and frame filter name.
397
398         Raises:
399             gdb.GdbError: An error parsing the arguments.
400         """
401
402         argv = gdb.string_to_argv(arg);
403         argc = len(argv)
404         if argc != 2:
405             print("show frame-filter priority " \
406                   "takes exactly two arguments.")
407             return None
408
409         return argv
410
411     def get_filter_priority(self, frame_filters, name):
412         """Worker for retrieving the priority of frame_filters.
413
414         Arguments:
415             frame_filters: Name of frame filter dictionary.
416             name: object to select printers.
417
418         Returns:
419             The priority of the frame filter.
420
421         Raises:
422             gdb.GdbError: A frame filter cannot be found.
423         """
424
425         op_list = gdb.frames.return_list(frame_filters)
426
427         try:
428             ff = op_list[name]
429         except KeyError:
430             msg = "frame-filter '" + str(name) + "' not found."
431             raise gdb.GdbError(msg)
432
433         return gdb.frames.get_priority(ff)
434
435     def complete(self, text, word):
436         """Completion function for both frame filter dictionary, and
437         frame filter name."""
438
439         if text.count(" ") == 0:
440             return _complete_frame_filter_list(text, word, False)
441         else:
442             printer_list = frame._return_list(text.split()[0].rstrip())
443             return _complete_frame_filter_name(word, printer_list)
444
445     def invoke(self, arg, from_tty):
446         command_tuple = self._parse_pri_arg(arg)
447         if command_tuple == None:
448             return
449         filter_name = command_tuple[1]
450         list_name = command_tuple[0]
451         try:
452             priority = self.get_filter_priority(list_name, filter_name);
453         except Exception:
454             e = sys.exc_info()[1]
455             print("Error printing filter priority for '"+name+"':"+str(e))
456         else:
457             print("Priority of filter '" + filter_name + "' in list '" \
458                 + list_name + "' is: " + str(priority))
459
460 # Register commands
461 SetFilterPrefixCmd()
462 ShowFilterPrefixCmd()
463 InfoFrameFilter()
464 EnableFrameFilter()
465 DisableFrameFilter()
466 SetFrameFilterPriority()
467 ShowFrameFilterPriority()
This page took 0.043472 seconds and 2 git commands to generate.