GDB (xrefs)

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