]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/python/lib/gdb/command/unwinders.py
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / python / lib / gdb / command / unwinders.py
CommitLineData
d11916aa 1# Unwinder commands.
1d506c26 2# Copyright 2015-2024 Free Software Foundation, Inc.
d11916aa
SS
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
17import gdb
18import re
19
20
21def validate_regexp(exp, idstring):
22 try:
23 return re.compile(exp)
24 except SyntaxError:
25 raise SyntaxError("Invalid %s regexp: %s." % (idstring, exp))
26
27
28def parse_unwinder_command_args(arg):
29 """Internal utility to parse unwinder command argv.
30
31 Arguments:
32 arg: The arguments to the command. The format is:
33 [locus-regexp [name-regexp]]
34
35 Returns:
36 A 2-tuple of compiled regular expressions.
37
38 Raises:
39 SyntaxError: an error processing ARG
40 """
41
42 argv = gdb.string_to_argv(arg)
43 argc = len(argv)
44 if argc > 2:
45 raise SyntaxError("Too many arguments.")
46 locus_regexp = ""
47 name_regexp = ""
48 if argc >= 1:
49 locus_regexp = argv[0]
50 if argc >= 2:
51 name_regexp = argv[1]
13123da8
SM
52 return (
53 validate_regexp(locus_regexp, "locus"),
54 validate_regexp(name_regexp, "unwinder"),
55 )
d11916aa
SS
56
57
58class InfoUnwinder(gdb.Command):
59 """GDB command to list unwinders.
60
13123da8 61 Usage: info unwinder [LOCUS-REGEXP [NAME-REGEXP]]
d11916aa 62
13123da8
SM
63 LOCUS-REGEXP is a regular expression matching the location of the
64 unwinder. If it is omitted, all registered unwinders from all
65 loci are listed. A locus can be 'global', 'progspace' to list
66 the unwinders from the current progspace, or a regular expression
67 matching filenames of objfiles.
d11916aa 68
13123da8
SM
69 NAME-REGEXP is a regular expression to filter unwinder names. If
70 this omitted for a specified locus, then all registered unwinders
71 in the locus are listed."""
d11916aa
SS
72
73 def __init__(self):
13123da8 74 super(InfoUnwinder, self).__init__("info unwinder", gdb.COMMAND_STACK)
d11916aa
SS
75
76 def list_unwinders(self, title, unwinders, name_re):
77 """Lists the unwinders whose name matches regexp.
78
79 Arguments:
80 title: The line to print before the list.
81 unwinders: The list of the unwinders.
82 name_re: unwinder name filter.
83 """
84 if not unwinders:
85 return
40d2f8d6 86 print(title)
d11916aa
SS
87 for unwinder in unwinders:
88 if name_re.match(unwinder.name):
13123da8
SM
89 print(
90 " %s%s"
91 % (unwinder.name, "" if unwinder.enabled else " [disabled]")
92 )
d11916aa
SS
93
94 def invoke(self, arg, from_tty):
95 locus_re, name_re = parse_unwinder_command_args(arg)
96 if locus_re.match("global"):
13123da8 97 self.list_unwinders("Global:", gdb.frame_unwinders, name_re)
d11916aa
SS
98 if locus_re.match("progspace"):
99 cp = gdb.current_progspace()
13123da8
SM
100 self.list_unwinders(
101 "Progspace %s:" % cp.filename, cp.frame_unwinders, name_re
102 )
d11916aa
SS
103 for objfile in gdb.objfiles():
104 if locus_re.match(objfile.filename):
13123da8
SM
105 self.list_unwinders(
106 "Objfile %s:" % objfile.filename, objfile.frame_unwinders, name_re
107 )
d11916aa
SS
108
109
110def do_enable_unwinder1(unwinders, name_re, flag):
111 """Enable/disable unwinders whose names match given regex.
112
113 Arguments:
114 unwinders: The list of unwinders.
115 name_re: Unwinder name filter.
116 flag: Enable/disable.
117
118 Returns:
119 The number of unwinders affected.
120 """
121 total = 0
122 for unwinder in unwinders:
123 if name_re.match(unwinder.name):
124 unwinder.enabled = flag
125 total += 1
126 return total
127
128
129def do_enable_unwinder(arg, flag):
130 """Enable/disable unwinder(s)."""
131 (locus_re, name_re) = parse_unwinder_command_args(arg)
132 total = 0
133 if locus_re.match("global"):
134 total += do_enable_unwinder1(gdb.frame_unwinders, name_re, flag)
135 if locus_re.match("progspace"):
13123da8
SM
136 total += do_enable_unwinder1(
137 gdb.current_progspace().frame_unwinders, name_re, flag
138 )
d11916aa
SS
139 for objfile in gdb.objfiles():
140 if locus_re.match(objfile.filename):
13123da8 141 total += do_enable_unwinder1(objfile.frame_unwinders, name_re, flag)
e0f3fd7c
TT
142 if total > 0:
143 gdb.invalidate_cached_frames()
13123da8
SM
144 print(
145 "%d unwinder%s %s"
146 % (total, "" if total == 1 else "s", "enabled" if flag else "disabled")
147 )
d11916aa
SS
148
149
150class EnableUnwinder(gdb.Command):
151 """GDB command to enable unwinders.
152
13123da8 153 Usage: enable unwinder [LOCUS-REGEXP [NAME-REGEXP]]
d11916aa 154
13123da8
SM
155 LOCUS-REGEXP is a regular expression specifying the unwinders to
156 enable. It can 'global', 'progspace', or the name of an objfile
157 within that progspace.
d11916aa 158
13123da8
SM
159 NAME_REGEXP is a regular expression to filter unwinder names. If
160 this omitted for a specified locus, then all registered unwinders
161 in the locus are affected."""
d11916aa
SS
162
163 def __init__(self):
13123da8 164 super(EnableUnwinder, self).__init__("enable unwinder", gdb.COMMAND_STACK)
d11916aa
SS
165
166 def invoke(self, arg, from_tty):
167 """GDB calls this to perform the command."""
168 do_enable_unwinder(arg, True)
169
170
171class DisableUnwinder(gdb.Command):
172 """GDB command to disable the specified unwinder.
173
13123da8 174 Usage: disable unwinder [LOCUS-REGEXP [NAME-REGEXP]]
d11916aa 175
13123da8
SM
176 LOCUS-REGEXP is a regular expression specifying the unwinders to
177 disable. It can 'global', 'progspace', or the name of an objfile
178 within that progspace.
d11916aa 179
13123da8
SM
180 NAME_REGEXP is a regular expression to filter unwinder names. If
181 this omitted for a specified locus, then all registered unwinders
182 in the locus are affected."""
d11916aa
SS
183
184 def __init__(self):
13123da8 185 super(DisableUnwinder, self).__init__("disable unwinder", gdb.COMMAND_STACK)
d11916aa
SS
186
187 def invoke(self, arg, from_tty):
188 """GDB calls this to perform the command."""
189 do_enable_unwinder(arg, False)
190
191
192def register_unwinder_commands():
193 """Installs the unwinder commands."""
194 InfoUnwinder()
195 EnableUnwinder()
196 DisableUnwinder()
197
198
199register_unwinder_commands()