GDB (xrefs)
xmethods.py
Go to the documentation of this file.
1 # Xmethod commands.
2 # Copyright 2013-2015 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 """GDB commands for working with xmethods."""
21 
22 
23 def validate_xm_regexp(part_name, regexp):
24  try:
25  return re.compile(regexp)
26  except SyntaxError:
27  raise SyntaxError("Invalid %s regexp: %s", part_name, regexp)
28 
29 
31  """Parses the arguments passed to a xmethod command.
32 
33  Arguments:
34  arg: The argument string passed to a xmethod command.
35 
36  Returns:
37  A 3-tuple: (<locus matching regular expression>,
38  <matcher matching regular expression>,
39  <name matching regular experession>)
40  """
41  argv = gdb.string_to_argv(arg)
42  argc = len(argv)
43  if argc > 2:
44  raise SyntaxError("Too many arguments to command.")
45  locus_regexp = ""
46  matcher_name_regexp = ""
47  xm_name_regexp = None
48  if argc >= 1:
49  locus_regexp = argv[0]
50  if argc == 2:
51  parts = argv[1].split(";", 1)
52  matcher_name_regexp = parts[0]
53  if len(parts) > 1:
54  xm_name_regexp = parts[1]
55  if xm_name_regexp:
56  name_re = validate_xm_regexp("xmethod name", xm_name_regexp)
57  else:
58  name_re = None
59  return (validate_xm_regexp("locus", locus_regexp),
60  validate_xm_regexp("matcher name", matcher_name_regexp),
61  name_re)
62 
63 
64 def get_global_method_matchers(locus_re, matcher_re):
65  """Returns a dict of matching globally registered xmethods.
66 
67  Arguments:
68  locus_re: Even though only globally registered xmethods are
69  looked up, they will be looked up only if 'global' matches
70  LOCUS_RE.
71  matcher_re: The regular expression matching the names of xmethods.
72 
73  Returns:
74  A dict of matching globally registered xmethod matchers. The only
75  key in the dict will be 'global'.
76  """
77  locus_str = "global"
78  xm_dict = { locus_str: [] }
79  if locus_re.match("global"):
80  xm_dict[locus_str].extend(
81  [m for m in gdb.xmethods if matcher_re.match(m.name)])
82  return xm_dict
83 
84 
85 def get_method_matchers_in_loci(loci, locus_re, matcher_re):
86  """Returns a dict of matching registered xmethods in the LOCI.
87 
88  Arguments:
89  loci: The list of loci to lookup matching xmethods in.
90  locus_re: If a locus is an objfile, then xmethod matchers will be
91  looked up in it only if its filename matches the regular
92  expression LOCUS_RE. If a locus is the current progspace,
93  then xmethod matchers will be looked up in it only if the
94  string "progspace" matches LOCUS_RE.
95  matcher_re: The regular expression to match the xmethod matcher
96  names.
97 
98  Returns:
99  A dict of matching xmethod matchers. The keys of the dict are the
100  filenames of the loci the xmethod matchers belong to.
101  """
102  xm_dict = {}
103  for locus in loci:
104  if isinstance(locus, gdb.Progspace):
105  if not locus_re.match('progspace'):
106  continue
107  locus_type = "progspace"
108  else:
109  if not locus_re.match(locus.filename):
110  continue
111  locus_type = "objfile"
112  locus_str = "%s %s" % (locus_type, locus.filename)
113  xm_dict[locus_str] = [
114  m for m in locus.xmethods if matcher_re.match(m.name)]
115  return xm_dict
116 
117 
118 def print_xm_info(xm_dict, name_re):
119  """Print a dictionary of xmethods."""
120  def get_status_string(m):
121  if not m.enabled:
122  return " [disabled]"
123  else:
124  return ""
125 
126  if not xm_dict:
127  return
128  for locus_str in xm_dict:
129  if not xm_dict[locus_str]:
130  continue
131  print ("Xmethods in %s:" % locus_str)
132  for matcher in xm_dict[locus_str]:
133  print (" %s%s" % (matcher.name, get_status_string(matcher)))
134  if not matcher.methods:
135  continue
136  for m in matcher.methods:
137  if name_re is None or name_re.match(m.name):
138  print (" %s%s" % (m.name, get_status_string(m)))
139 
140 
141 def set_xm_status1(xm_dict, name_re, status):
142  """Set the status (enabled/disabled) of a dictionary of xmethods."""
143  for locus_str, matchers in xm_dict.items():
144  for matcher in matchers:
145  if not name_re:
146  # If the name regex is missing, then set the status of the
147  # matcher and move on.
148  matcher.enabled = status
149  continue
150  if not matcher.methods:
151  # The methods attribute could be None. Move on.
152  continue
153  for m in matcher.methods:
154  if name_re.match(m.name):
155  m.enabled = status
156 
157 
158 def set_xm_status(arg, status):
159  """Set the status (enabled/disabled) of xmethods matching ARG.
160  This is a helper function for enable/disable commands. ARG is the
161  argument string passed to the commands.
162  """
163  locus_re, matcher_re, name_re = parse_xm_command_args(arg)
164  set_xm_status1(get_global_method_matchers(locus_re, matcher_re), name_re,
165  status)
168  [gdb.current_progspace()], locus_re, matcher_re),
169  name_re,
170  status)
172  get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re),
173  name_re,
174  status)
175 
176 
177 class InfoXMethod(gdb.Command):
178  """GDB command to list registered xmethod matchers.
179 
180  Usage: info xmethod [locus-regexp [name-regexp]]
181 
182  LOCUS-REGEXP is a regular expression matching the location of the
183  xmethod matchers. If it is omitted, all registered xmethod matchers
184  from all loci are listed. A locus could be 'global', a regular expression
185  matching the current program space's filename, or a regular expression
186  matching filenames of objfiles. Locus could be 'progspace' to specify that
187  only xmethods from the current progspace should be listed.
188 
189  NAME-REGEXP is a regular expression matching the names of xmethod
190  matchers. If this omitted for a specified locus, then all registered
191  xmethods in the locus are listed. To list only a certain xmethods
192  managed by a single matcher, the name regexp can be specified as
193  matcher-name-regexp;xmethod-name-regexp.
194  """
195 
196  def __init__(self):
197  super(InfoXMethod, self).__init__("info xmethod",
198  gdb.COMMAND_DATA)
199 
200  def invoke(self, arg, from_tty):
201  locus_re, matcher_re, name_re = parse_xm_command_args(arg)
202  print_xm_info(get_global_method_matchers(locus_re, matcher_re),
203  name_re)
206  [gdb.current_progspace()], locus_re, matcher_re),
207  name_re)
209  get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re),
210  name_re)
211 
212 
213 class EnableXMethod(gdb.Command):
214  """GDB command to enable a specified (group of) xmethod(s).
215 
216  Usage: enable xmethod [locus-regexp [name-regexp]]
217 
218  LOCUS-REGEXP is a regular expression matching the location of the
219  xmethod matchers. If it is omitted, all registered xmethods matchers
220  from all loci are enabled. A locus could be 'global', a regular expression
221  matching the current program space's filename, or a regular expression
222  matching filenames of objfiles. Locus could be 'progspace' to specify that
223  only xmethods from the current progspace should be enabled.
224 
225  NAME-REGEXP is a regular expression matching the names of xmethods
226  within a given locus. If this omitted for a specified locus, then all
227  registered xmethod matchers in the locus are enabled. To enable only
228  a certain xmethods managed by a single matcher, the name regexp can be
229  specified as matcher-name-regexp;xmethod-name-regexp.
230  """
231 
232  def __init__(self):
233  super(EnableXMethod, self).__init__("enable xmethod",
234  gdb.COMMAND_DATA)
235 
236  def invoke(self, arg, from_tty):
237  set_xm_status(arg, True)
238 
239 
240 class DisableXMethod(gdb.Command):
241  """GDB command to disable a specified (group of) xmethod(s).
242 
243  Usage: disable xmethod [locus-regexp [name-regexp]]
244 
245  LOCUS-REGEXP is a regular expression matching the location of the
246  xmethod matchers. If it is omitted, all registered xmethod matchers
247  from all loci are disabled. A locus could be 'global', a regular
248  expression matching the current program space's filename, or a regular
249  expression filenames of objfiles. Locus could be 'progspace' to specify
250  that only xmethods from the current progspace should be disabled.
251 
252  NAME-REGEXP is a regular expression matching the names of xmethods
253  within a given locus. If this omitted for a specified locus, then all
254  registered xmethod matchers in the locus are disabled. To disable
255  only a certain xmethods managed by a single matcher, the name regexp
256  can be specified as matcher-name-regexp;xmethod-name-regexp.
257  """
258 
259  def __init__(self):
260  super(DisableXMethod, self).__init__("disable xmethod",
261  gdb.COMMAND_DATA)
262 
263  def invoke(self, arg, from_tty):
264  set_xm_status(arg, False)
265 
266 
268  """Installs the xmethod commands."""
269  InfoXMethod()
270  EnableXMethod()
272 
273 
def parse_xm_command_args(arg)
Definition: xmethods.py:30
def set_xm_status(arg, status)
Definition: xmethods.py:158
def get_method_matchers_in_loci(loci, locus_re, matcher_re)
Definition: xmethods.py:85
def get_global_method_matchers(locus_re, matcher_re)
Definition: xmethods.py:64
def validate_xm_regexp(part_name, regexp)
Definition: xmethods.py:23
def set_xm_status1(xm_dict, name_re, status)
Definition: xmethods.py:141
def print_xm_info(xm_dict, name_re)
Definition: xmethods.py:118
def invoke(self, arg, from_tty)
Definition: xmethods.py:263
def invoke(self, arg, from_tty)
Definition: xmethods.py:236
def register_xmethod_commands()
Definition: xmethods.py:267
def invoke(self, arg, from_tty)
Definition: xmethods.py:200
const ULONGEST const LONGEST len
Definition: target.h:309