]>
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-2023 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."""
24 class SetFilterPrefixCmd(gdb
.Command
):
25 """Prefix command for 'set' frame-filter related operations."""
28 super(SetFilterPrefixCmd
, self
).__init
__(
29 "set frame-filter", gdb
.COMMAND_OBSCURE
, gdb
.COMPLETE_NONE
, True
33 class ShowFilterPrefixCmd(gdb
.Command
):
34 """Prefix command for 'show' frame-filter related operations."""
37 super(ShowFilterPrefixCmd
, self
).__init
__(
38 "show frame-filter", gdb
.COMMAND_OBSCURE
, gdb
.COMPLETE_NONE
, True
42 class InfoFrameFilter(gdb
.Command
):
43 """List all registered Python frame-filters.
45 Usage: info frame-filters"""
48 super(InfoFrameFilter
, self
).__init
__("info frame-filter", gdb
.COMMAND_DATA
)
51 def enabled_string(state
):
52 """Return "Yes" if filter is enabled, otherwise "No"."""
58 def print_list(self
, title
, frame_filters
, blank_line
):
59 sorted_frame_filters
= sorted(
60 frame_filters
.items(),
61 key
=lambda i
: gdb
.frames
.get_priority(i
[1]),
65 if len(sorted_frame_filters
) == 0:
69 print(" Priority Enabled Name")
70 for frame_filter
in sorted_frame_filters
:
71 name
= frame_filter
[0]
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]))
77 print(" %s %s %s" % (priority
, enabled
, name
))
80 print(" Error printing filter '" + name
+ "': " + str(e
))
85 def invoke(self
, arg
, from_tty
):
86 any_printed
= self
.print_list("global frame-filters:", gdb
.frame_filters
, True)
88 cp
= gdb
.current_progspace()
89 any_printed
+= self
.print_list(
90 "progspace %s frame-filters:" % cp
.filename
, cp
.frame_filters
, True
93 for objfile
in gdb
.objfiles():
94 any_printed
+= self
.print_list(
95 "objfile %s frame-filters:" % objfile
.filename
,
96 objfile
.frame_filters
,
101 print("No frame filters.")
104 # Internal enable/disable functions.
107 def _enable_parse_arg(cmd_name
, arg
):
108 """Internal worker function to take an argument from
109 enable/disable and return a tuple of arguments.
112 cmd_name: Name of the command invoking this function.
113 args: The argument as a string.
116 A tuple containing the dictionary, and the argument, or just
117 the dictionary in the case of "all".
120 argv
= gdb
.string_to_argv(arg
)
123 raise gdb
.GdbError(cmd_name
+ " requires an argument")
127 cmd_name
+ ": with 'all' " "you may not specify a filter."
130 raise gdb
.GdbError(cmd_name
+ " takes exactly two arguments.")
135 def _do_enable_frame_filter(command_tuple
, flag
):
136 """Worker for enabling/disabling frame_filters.
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.
145 list_op
= command_tuple
[0]
146 op_list
= gdb
.frames
.return_list(list_op
)
150 gdb
.frames
.set_enabled(item
, flag
)
152 frame_filter
= command_tuple
[1]
154 ff
= op_list
[frame_filter
]
156 msg
= "frame-filter '" + str(frame_filter
) + "' not found."
157 raise gdb
.GdbError(msg
)
159 gdb
.frames
.set_enabled(ff
, flag
)
162 def _complete_frame_filter_list(text
, word
, all_flag
):
163 """Worker for frame filter dictionary name completion.
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.
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.
176 filter_locations
= ["all", "global", "progspace"]
178 filter_locations
= ["global", "progspace"]
179 for objfile
in gdb
.objfiles():
180 filter_locations
.append(objfile
.filename
)
182 # If the user just asked for completions with no completion
183 # hints, just return all the frame filter dictionaries we know
186 return filter_locations
188 # Otherwise filter on what we know.
189 flist
= filter(lambda x
, y
=text
: x
.startswith(y
), filter_locations
)
191 # If we only have one completion, complete it and return it.
193 flist
[0] = flist
[0][len(text
) - len(word
) :]
195 # Otherwise, return an empty list, or a list of frame filter
196 # dictionaries that the previous filter operation returned.
200 def _complete_frame_filter_name(word
, printer_dict
):
201 """Worker for frame filter name completion.
205 word: The most recent word of the command line.
207 printer_dict: The frame filter dictionary to search for frame
208 filter name completions.
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.
215 printer_keys
= printer_dict
.keys()
219 flist
= filter(lambda x
, y
=word
: x
.startswith(y
), printer_keys
)
223 class EnableFrameFilter(gdb
.Command
):
224 """GDB command to enable the specified frame-filter.
226 Usage: enable frame-filter DICTIONARY [NAME]
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.
236 NAME matches the name of the frame-filter to operate on."""
239 super(EnableFrameFilter
, self
).__init
__("enable frame-filter", gdb
.COMMAND_DATA
)
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)
247 printer_list
= gdb
.frames
.return_list(text
.split()[0].rstrip())
248 return _complete_frame_filter_name(word
, printer_list
)
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)
255 class DisableFrameFilter(gdb
.Command
):
256 """GDB command to disable the specified frame-filter.
258 Usage: disable frame-filter DICTIONARY [NAME]
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.
268 NAME matches the name of the frame-filter to operate on."""
271 super(DisableFrameFilter
, self
).__init
__(
272 "disable frame-filter", gdb
.COMMAND_DATA
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)
281 printer_list
= gdb
.frames
.return_list(text
.split()[0].rstrip())
282 return _complete_frame_filter_name(word
, printer_list
)
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)
289 class SetFrameFilterPriority(gdb
.Command
):
290 """GDB command to set the priority of the specified frame-filter.
292 Usage: set frame-filter priority DICTIONARY NAME PRIORITY
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.
301 NAME matches the name of the frame filter to operate on.
303 PRIORITY is the an integer to assign the new priority to the frame
307 super(SetFrameFilterPriority
, self
).__init
__(
308 "set frame-filter " "priority", gdb
.COMMAND_DATA
311 def _parse_pri_arg(self
, arg
):
312 """Internal worker to parse a priority from a tuple.
315 arg: Tuple which contains the arguments from the command.
318 A tuple containing the dictionary, name and priority from
322 gdb.GdbError: An error parsing the arguments.
325 argv
= gdb
.string_to_argv(arg
)
328 print("set frame-filter priority " "takes exactly three arguments.")
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
339 command_tuple: Tuple which contains the arguments from the
343 list_op
= command_tuple
[0]
344 frame_filter
= command_tuple
[1]
346 # GDB returns arguments as a string, so convert priority to
348 priority
= int(command_tuple
[2])
350 op_list
= gdb
.frames
.return_list(list_op
)
353 ff
= op_list
[frame_filter
]
355 msg
= "frame-filter '" + str(frame_filter
) + "' not found."
356 raise gdb
.GdbError(msg
)
358 gdb
.frames
.set_priority(ff
, priority
)
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)
366 printer_list
= gdb
.frames
.return_list(text
.split()[0].rstrip())
367 return _complete_frame_filter_name(word
, printer_list
)
369 def invoke(self
, arg
, from_tty
):
370 command_tuple
= self
._parse
_pri
_arg
(arg
)
371 if command_tuple
is not None:
372 self
._set
_filter
_priority
(command_tuple
)
375 class ShowFrameFilterPriority(gdb
.Command
):
376 """GDB command to show the priority of the specified frame-filter.
378 Usage: show frame-filter priority DICTIONARY NAME
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.
387 NAME matches the name of the frame-filter to operate on."""
390 super(ShowFrameFilterPriority
, self
).__init
__(
391 "show frame-filter " "priority", gdb
.COMMAND_DATA
394 def _parse_pri_arg(self
, arg
):
395 """Internal worker to parse a dictionary and name from a
399 arg: Tuple which contains the arguments from the command.
402 A tuple containing the dictionary, and frame filter name.
405 gdb.GdbError: An error parsing the arguments.
408 argv
= gdb
.string_to_argv(arg
)
411 print("show frame-filter priority " "takes exactly two arguments.")
416 def get_filter_priority(self
, frame_filters
, name
):
417 """Worker for retrieving the priority of frame_filters.
420 frame_filters: Name of frame filter dictionary.
421 name: object to select printers.
424 The priority of the frame filter.
427 gdb.GdbError: A frame filter cannot be found.
430 op_list
= gdb
.frames
.return_list(frame_filters
)
435 msg
= "frame-filter '" + str(name
) + "' not found."
436 raise gdb
.GdbError(msg
)
438 return gdb
.frames
.get_priority(ff
)
440 def complete(self
, text
, word
):
441 """Completion function for both frame filter dictionary, and
442 frame filter name."""
444 if text
.count(" ") == 0:
445 return _complete_frame_filter_list(text
, word
, False)
447 printer_list
= frame
._return
_list
(text
.split()[0].rstrip())
448 return _complete_frame_filter_name(word
, printer_list
)
450 def invoke(self
, arg
, from_tty
):
451 command_tuple
= self
._parse
_pri
_arg
(arg
)
452 if command_tuple
is None:
454 filter_name
= command_tuple
[1]
455 list_name
= command_tuple
[0]
457 priority
= self
.get_filter_priority(list_name
, filter_name
)
459 e
= sys
.exc_info()[1]
460 print("Error printing filter priority for '" + name
+ "':" + str(e
))
463 "Priority of filter '"
474 ShowFilterPrefixCmd()
478 SetFrameFilterPriority()
479 ShowFrameFilterPriority()