]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/lib/gdb/command/frame_filters.py
1 # Frame-filter commands.
2 # Copyright (C) 2013-2024 Free Software Foundation, Inc.
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.
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.
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/>.
17 """GDB commands for working with frame-filters."""
25 class SetFilterPrefixCmd(gdb
.Command
):
26 """Prefix command for 'set' frame-filter related operations."""
29 super(SetFilterPrefixCmd
, self
).__init
__(
30 "set frame-filter", gdb
.COMMAND_OBSCURE
, gdb
.COMPLETE_NONE
, True
34 class ShowFilterPrefixCmd(gdb
.Command
):
35 """Prefix command for 'show' frame-filter related operations."""
38 super(ShowFilterPrefixCmd
, self
).__init
__(
39 "show frame-filter", gdb
.COMMAND_OBSCURE
, gdb
.COMPLETE_NONE
, True
43 class InfoFrameFilter(gdb
.Command
):
44 """List all registered Python frame-filters.
46 Usage: info frame-filters"""
49 super(InfoFrameFilter
, self
).__init
__("info frame-filter", gdb
.COMMAND_DATA
)
52 def enabled_string(state
):
53 """Return "Yes" if filter is enabled, otherwise "No"."""
59 def print_list(self
, title
, frame_filters
, blank_line
):
60 sorted_frame_filters
= sorted(
61 frame_filters
.items(),
62 key
=lambda i
: gdb
.frames
.get_priority(i
[1]),
66 if len(sorted_frame_filters
) == 0:
70 print(" Priority Enabled Name")
71 for frame_filter
in sorted_frame_filters
:
72 name
= frame_filter
[0]
74 priority
= "{:<8}".format(str(gdb
.frames
.get_priority(frame_filter
[1])))
75 enabled
= "{:<7}".format(
76 self
.enabled_string(gdb
.frames
.get_enabled(frame_filter
[1]))
78 print(" %s %s %s" % (priority
, enabled
, name
))
81 print(" Error printing filter '" + name
+ "': " + str(e
))
86 def invoke(self
, arg
, from_tty
):
87 any_printed
= self
.print_list("global frame-filters:", gdb
.frame_filters
, True)
89 cp
= gdb
.current_progspace()
90 any_printed
+= self
.print_list(
91 "progspace %s frame-filters:" % cp
.filename
, cp
.frame_filters
, True
94 for objfile
in gdb
.objfiles():
95 any_printed
+= self
.print_list(
96 "objfile %s frame-filters:" % objfile
.filename
,
97 objfile
.frame_filters
,
102 print("No frame filters.")
105 # Internal enable/disable functions.
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.
113 cmd_name: Name of the command invoking this function.
114 args: The argument as a string.
117 A tuple containing the dictionary, and the argument, or just
118 the dictionary in the case of "all".
121 argv
= gdb
.string_to_argv(arg
)
124 raise gdb
.GdbError(cmd_name
+ " requires an argument")
128 cmd_name
+ ": with 'all' " "you may not specify a filter."
131 raise gdb
.GdbError(cmd_name
+ " takes exactly two arguments.")
136 def _do_enable_frame_filter(command_tuple
, flag
):
137 """Worker for enabling/disabling frame_filters.
140 command_type: A tuple with the first element being the
141 frame filter dictionary, and the second being
142 the frame filter name.
143 flag: True for Enable, False for Disable.
146 list_op
= command_tuple
[0]
147 op_list
= gdb
.frames
.return_list(list_op
)
151 gdb
.frames
.set_enabled(item
, flag
)
153 frame_filter
= command_tuple
[1]
155 ff
= op_list
[frame_filter
]
157 msg
= "frame-filter '" + str(frame_filter
) + "' not found."
158 raise gdb
.GdbError(msg
)
160 gdb
.frames
.set_enabled(ff
, flag
)
163 def _complete_frame_filter_list(text
, word
, all_flag
):
164 """Worker for frame filter dictionary name completion.
167 text: The full text of the command line.
168 word: The most recent word of the command line.
169 all_flag: Whether to include the word "all" in completion.
172 A list of suggested frame filter dictionary name completions
173 from text/word analysis. This list can be empty when there
174 are no suggestions for completion.
177 filter_locations
= ["all", "global", "progspace"]
179 filter_locations
= ["global", "progspace"]
180 for objfile
in gdb
.objfiles():
181 filter_locations
.append(objfile
.filename
)
183 # If the user just asked for completions with no completion
184 # hints, just return all the frame filter dictionaries we know
187 return filter_locations
189 # Otherwise filter on what we know.
190 flist
= filter(lambda x
, y
=text
: x
.startswith(y
), filter_locations
)
192 # If we only have one completion, complete it and return it.
194 flist
[0] = flist
[0][len(text
) - len(word
) :]
196 # Otherwise, return an empty list, or a list of frame filter
197 # dictionaries that the previous filter operation returned.
201 def _complete_frame_filter_name(word
, printer_dict
):
202 """Worker for frame filter name completion.
206 word: The most recent word of the command line.
208 printer_dict: The frame filter dictionary to search for frame
209 filter name completions.
211 Returns: A list of suggested frame filter name completions
212 from word analysis of the frame filter dictionary. This list
213 can be empty when there are no suggestions for completion.
216 printer_keys
= printer_dict
.keys()
220 flist
= filter(lambda x
, y
=word
: x
.startswith(y
), printer_keys
)
224 class EnableFrameFilter(gdb
.Command
):
225 """GDB command to enable the specified frame-filter.
227 Usage: enable frame-filter DICTIONARY [NAME]
229 DICTIONARY is the name of the frame filter dictionary on which to
230 operate. If dictionary is set to "all", perform operations on all
231 dictionaries. Named dictionaries are: "global" for the global
232 frame filter dictionary, "progspace" for the program space's frame
233 filter dictionary. If either all, or the two named dictionaries
234 are not specified, the dictionary name is assumed to be the name
235 of an "objfile" -- a shared library or an executable.
237 NAME matches the name of the frame-filter to operate on."""
240 super(EnableFrameFilter
, self
).__init
__("enable frame-filter", gdb
.COMMAND_DATA
)
242 def complete(self
, text
, word
):
243 """Completion function for both frame filter dictionary, and
244 frame filter name."""
245 if text
.count(" ") == 0:
246 return _complete_frame_filter_list(text
, word
, True)
248 printer_list
= gdb
.frames
.return_list(text
.split()[0].rstrip())
249 return _complete_frame_filter_name(word
, printer_list
)
251 def invoke(self
, arg
, from_tty
):
252 command_tuple
= _enable_parse_arg("enable frame-filter", arg
)
253 _do_enable_frame_filter(command_tuple
, True)
256 class DisableFrameFilter(gdb
.Command
):
257 """GDB command to disable the specified frame-filter.
259 Usage: disable frame-filter DICTIONARY [NAME]
261 DICTIONARY is the name of the frame filter dictionary on which to
262 operate. If dictionary is set to "all", perform operations on all
263 dictionaries. Named dictionaries are: "global" for the global
264 frame filter dictionary, "progspace" for the program space's frame
265 filter dictionary. If either all, or the two named dictionaries
266 are not specified, the dictionary name is assumed to be the name
267 of an "objfile" -- a shared library or an executable.
269 NAME matches the name of the frame-filter to operate on."""
272 super(DisableFrameFilter
, self
).__init
__(
273 "disable frame-filter", gdb
.COMMAND_DATA
276 def complete(self
, text
, word
):
277 """Completion function for both frame filter dictionary, and
278 frame filter name."""
279 if text
.count(" ") == 0:
280 return _complete_frame_filter_list(text
, word
, True)
282 printer_list
= gdb
.frames
.return_list(text
.split()[0].rstrip())
283 return _complete_frame_filter_name(word
, printer_list
)
285 def invoke(self
, arg
, from_tty
):
286 command_tuple
= _enable_parse_arg("disable frame-filter", arg
)
287 _do_enable_frame_filter(command_tuple
, False)
290 class SetFrameFilterPriority(gdb
.Command
):
291 """GDB command to set the priority of the specified frame-filter.
293 Usage: set frame-filter priority DICTIONARY NAME PRIORITY
295 DICTIONARY is the name of the frame filter dictionary on which to
296 operate. Named dictionaries are: "global" for the global frame
297 filter dictionary, "progspace" for the program space's framefilter
298 dictionary. If either of these two are not specified, the
299 dictionary name is assumed to be the name of an "objfile" -- a
300 shared library or an executable.
302 NAME matches the name of the frame filter to operate on.
304 PRIORITY is the an integer to assign the new priority to the frame
308 super(SetFrameFilterPriority
, self
).__init
__(
309 "set frame-filter " "priority", gdb
.COMMAND_DATA
312 def _parse_pri_arg(self
, arg
):
313 """Internal worker to parse a priority from a tuple.
316 arg: Tuple which contains the arguments from the command.
319 A tuple containing the dictionary, name and priority from
323 gdb.GdbError: An error parsing the arguments.
326 argv
= gdb
.string_to_argv(arg
)
329 print("set frame-filter priority " "takes exactly three arguments.")
334 def _set_filter_priority(self
, command_tuple
):
335 """Internal worker for setting priority of frame-filters, by
336 parsing a tuple and calling _set_priority with the parsed
340 command_tuple: Tuple which contains the arguments from the
344 list_op
= command_tuple
[0]
345 frame_filter
= command_tuple
[1]
347 # GDB returns arguments as a string, so convert priority to
349 priority
= int(command_tuple
[2])
351 op_list
= gdb
.frames
.return_list(list_op
)
354 ff
= op_list
[frame_filter
]
356 msg
= "frame-filter '" + str(frame_filter
) + "' not found."
357 raise gdb
.GdbError(msg
)
359 gdb
.frames
.set_priority(ff
, priority
)
361 def complete(self
, text
, word
):
362 """Completion function for both frame filter dictionary, and
363 frame filter name."""
364 if text
.count(" ") == 0:
365 return _complete_frame_filter_list(text
, word
, False)
367 printer_list
= gdb
.frames
.return_list(text
.split()[0].rstrip())
368 return _complete_frame_filter_name(word
, printer_list
)
370 def invoke(self
, arg
, from_tty
):
371 command_tuple
= self
._parse
_pri
_arg
(arg
)
372 if command_tuple
is not None:
373 self
._set
_filter
_priority
(command_tuple
)
376 class ShowFrameFilterPriority(gdb
.Command
):
377 """GDB command to show the priority of the specified frame-filter.
379 Usage: show frame-filter priority DICTIONARY NAME
381 DICTIONARY is the name of the frame filter dictionary on which to
382 operate. Named dictionaries are: "global" for the global frame
383 filter dictionary, "progspace" for the program space's framefilter
384 dictionary. If either of these two are not specified, the
385 dictionary name is assumed to be the name of an "objfile" -- a
386 shared library or an executable.
388 NAME matches the name of the frame-filter to operate on."""
391 super(ShowFrameFilterPriority
, self
).__init
__(
392 "show frame-filter " "priority", gdb
.COMMAND_DATA
395 def _parse_pri_arg(self
, arg
):
396 """Internal worker to parse a dictionary and name from a
400 arg: Tuple which contains the arguments from the command.
403 A tuple containing the dictionary, and frame filter name.
406 gdb.GdbError: An error parsing the arguments.
409 argv
= gdb
.string_to_argv(arg
)
412 print("show frame-filter priority " "takes exactly two arguments.")
417 def get_filter_priority(self
, frame_filters
, name
):
418 """Worker for retrieving the priority of frame_filters.
421 frame_filters: Name of frame filter dictionary.
422 name: object to select printers.
425 The priority of the frame filter.
428 gdb.GdbError: A frame filter cannot be found.
431 op_list
= gdb
.frames
.return_list(frame_filters
)
436 msg
= "frame-filter '" + str(name
) + "' not found."
437 raise gdb
.GdbError(msg
)
439 return gdb
.frames
.get_priority(ff
)
441 def complete(self
, text
, word
):
442 """Completion function for both frame filter dictionary, and
443 frame filter name."""
445 if text
.count(" ") == 0:
446 return _complete_frame_filter_list(text
, word
, False)
448 printer_list
= frame
._return
_list
(text
.split()[0].rstrip())
449 return _complete_frame_filter_name(word
, printer_list
)
451 def invoke(self
, arg
, from_tty
):
452 command_tuple
= self
._parse
_pri
_arg
(arg
)
453 if command_tuple
is None:
455 filter_name
= command_tuple
[1]
456 list_name
= command_tuple
[0]
458 priority
= self
.get_filter_priority(list_name
, filter_name
)
460 e
= sys
.exc_info()[1]
461 print("Error printing filter priority for '" + name
+ "':" + str(e
))
464 "Priority of filter '"
475 ShowFilterPrefixCmd()
479 SetFrameFilterPriority()
480 ShowFrameFilterPriority()