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