]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/lib/gdb/command/unwinders.py
Update copyright year range in all GDB files
[thirdparty/binutils-gdb.git] / gdb / python / lib / gdb / command / unwinders.py
1 # Unwinder commands.
2 # Copyright 2015-2018 Free Software Foundation, Inc.
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 import gdb
18 import re
19
20
21 def 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
28 def 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]
52 return (validate_regexp(locus_regexp, "locus"),
53 validate_regexp(name_regexp, "unwinder"))
54
55
56 class InfoUnwinder(gdb.Command):
57 """GDB command to list unwinders.
58
59 Usage: info unwinder [locus-regexp [name-regexp]]
60
61 LOCUS-REGEXP is a regular expression matching the location of the
62 unwinder. If it is omitted, all registered unwinders from all
63 loci are listed. A locus can be 'global', 'progspace' to list
64 the unwinders from the current progspace, or a regular expression
65 matching filenames of objfiles.
66
67 NAME-REGEXP is a regular expression to filter unwinder names. If
68 this omitted for a specified locus, then all registered unwinders
69 in the locus are listed.
70 """
71
72 def __init__(self):
73 super(InfoUnwinder, self).__init__("info unwinder",
74 gdb.COMMAND_STACK)
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
86 print(title)
87 for unwinder in unwinders:
88 if name_re.match(unwinder.name):
89 print(" %s%s" % (unwinder.name,
90 "" if unwinder.enabled else " [disabled]"))
91
92 def invoke(self, arg, from_tty):
93 locus_re, name_re = parse_unwinder_command_args(arg)
94 if locus_re.match("global"):
95 self.list_unwinders("Global:", gdb.frame_unwinders,
96 name_re)
97 if locus_re.match("progspace"):
98 cp = gdb.current_progspace()
99 self.list_unwinders("Progspace %s:" % cp.filename,
100 cp.frame_unwinders, name_re)
101 for objfile in gdb.objfiles():
102 if locus_re.match(objfile.filename):
103 self.list_unwinders("Objfile %s:" % objfile.filename,
104 objfile.frame_unwinders, name_re)
105
106
107 def do_enable_unwinder1(unwinders, name_re, flag):
108 """Enable/disable unwinders whose names match given regex.
109
110 Arguments:
111 unwinders: The list of unwinders.
112 name_re: Unwinder name filter.
113 flag: Enable/disable.
114
115 Returns:
116 The number of unwinders affected.
117 """
118 total = 0
119 for unwinder in unwinders:
120 if name_re.match(unwinder.name):
121 unwinder.enabled = flag
122 total += 1
123 return total
124
125
126 def do_enable_unwinder(arg, flag):
127 """Enable/disable unwinder(s)."""
128 (locus_re, name_re) = parse_unwinder_command_args(arg)
129 total = 0
130 if locus_re.match("global"):
131 total += do_enable_unwinder1(gdb.frame_unwinders, name_re, flag)
132 if locus_re.match("progspace"):
133 total += do_enable_unwinder1(gdb.current_progspace().frame_unwinders,
134 name_re, flag)
135 for objfile in gdb.objfiles():
136 if locus_re.match(objfile.filename):
137 total += do_enable_unwinder1(objfile.frame_unwinders, name_re,
138 flag)
139 if total > 0:
140 gdb.invalidate_cached_frames()
141 print("%d unwinder%s %s" % (total, "" if total == 1 else "s",
142 "enabled" if flag else "disabled"))
143
144
145 class EnableUnwinder(gdb.Command):
146 """GDB command to enable unwinders.
147
148 Usage: enable unwinder [locus-regexp [name-regexp]]
149
150 LOCUS-REGEXP is a regular expression specifying the unwinders to
151 enable. It can 'global', 'progspace', or the name of an objfile
152 within that progspace.
153
154 NAME_REGEXP is a regular expression to filter unwinder names. If
155 this omitted for a specified locus, then all registered unwinders
156 in the locus are affected.
157
158 """
159
160 def __init__(self):
161 super(EnableUnwinder, self).__init__("enable unwinder",
162 gdb.COMMAND_STACK)
163
164 def invoke(self, arg, from_tty):
165 """GDB calls this to perform the command."""
166 do_enable_unwinder(arg, True)
167
168
169 class DisableUnwinder(gdb.Command):
170 """GDB command to disable the specified unwinder.
171
172 Usage: disable unwinder [locus-regexp [name-regexp]]
173
174 LOCUS-REGEXP is a regular expression specifying the unwinders to
175 disable. It can 'global', 'progspace', or the name of an objfile
176 within that progspace.
177
178 NAME_REGEXP is a regular expression to filter unwinder names. If
179 this omitted for a specified locus, then all registered unwinders
180 in the locus are affected.
181
182 """
183
184 def __init__(self):
185 super(DisableUnwinder, self).__init__("disable unwinder",
186 gdb.COMMAND_STACK)
187
188 def invoke(self, arg, from_tty):
189 """GDB calls this to perform the command."""
190 do_enable_unwinder(arg, False)
191
192
193 def register_unwinder_commands():
194 """Installs the unwinder commands."""
195 InfoUnwinder()
196 EnableUnwinder()
197 DisableUnwinder()
198
199
200 register_unwinder_commands()