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