]> Git Repo - binutils.git/blob - gdb/python/lib/gdb/command/unwinders.py
028ad7dec1bb08e250c19288c39f8fc320d9c822
[binutils.git] / gdb / python / lib / gdb / command / unwinders.py
1 # Unwinder commands.
2 # Copyright 2015-2019 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     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
85         print(title)
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
106 def 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
125 def 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)
138     if total > 0:
139         gdb.invalidate_cached_frames()
140     print("%d unwinder%s %s" % (total, "" if total == 1 else "s",
141                                 "enabled" if flag else "disabled"))
142
143
144 class EnableUnwinder(gdb.Command):
145     """GDB command to enable unwinders.
146
147 Usage: enable unwinder [LOCUS-REGEXP [NAME-REGEXP]]
148
149 LOCUS-REGEXP is a regular expression specifying the unwinders to
150 enable.  It can 'global', 'progspace', or the name of an objfile
151 within that progspace.
152
153 NAME_REGEXP is a regular expression to filter unwinder names.  If
154 this omitted for a specified locus, then all registered unwinders
155 in the locus are affected."""
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
166 class DisableUnwinder(gdb.Command):
167     """GDB command to disable the specified unwinder.
168
169 Usage: disable unwinder [LOCUS-REGEXP [NAME-REGEXP]]
170
171 LOCUS-REGEXP is a regular expression specifying the unwinders to
172 disable.  It can 'global', 'progspace', or the name of an objfile
173 within that progspace.
174
175 NAME_REGEXP is a regular expression to filter unwinder names.  If
176 this omitted for a specified locus, then all registered unwinders
177 in the locus are affected."""
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
188 def register_unwinder_commands():
189     """Installs the unwinder commands."""
190     InfoUnwinder()
191     EnableUnwinder()
192     DisableUnwinder()
193
194
195 register_unwinder_commands()
This page took 0.026831 seconds and 2 git commands to generate.