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