GDB (xrefs)
frames.py
Go to the documentation of this file.
1 # Frame-filter commands.
2 # Copyright (C) 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 """Internal functions for working with frame-filters."""
18 
19 import gdb
20 from gdb.FrameIterator import FrameIterator
21 from gdb.FrameDecorator import FrameDecorator
22 import itertools
23 import collections
24 
25 def get_priority(filter_item):
26  """ Internal worker function to return the frame-filter's priority
27  from a frame filter object. This is a fail free function as it is
28  used in sorting and filtering. If a badly implemented frame
29  filter does not implement the priority attribute, return zero
30  (otherwise sorting/filtering will fail and prevent other frame
31  filters from executing).
32 
33  Arguments:
34  filter_item: An object conforming to the frame filter
35  interface.
36 
37  Returns:
38  The priority of the frame filter from the "priority"
39  attribute, or zero.
40  """
41  # Do not fail here, as the sort will fail. If a filter has not
42  # (incorrectly) set a priority, set it to zero.
43  return getattr(filter_item, "priority", 0)
44 
45 def set_priority(filter_item, priority):
46  """ Internal worker function to set the frame-filter's priority.
47 
48  Arguments:
49  filter_item: An object conforming to the frame filter
50  interface.
51  priority: The priority to assign as an integer.
52  """
53 
54  filter_item.priority = priority
55 
56 def get_enabled(filter_item):
57  """ Internal worker function to return a filter's enabled state
58  from a frame filter object. This is a fail free function as it is
59  used in sorting and filtering. If a badly implemented frame
60  filter does not implement the enabled attribute, return False
61  (otherwise sorting/filtering will fail and prevent other frame
62  filters from executing).
63 
64  Arguments:
65  filter_item: An object conforming to the frame filter
66  interface.
67 
68  Returns:
69  The enabled state of the frame filter from the "enabled"
70  attribute, or False.
71  """
72 
73  # If the filter class is badly implemented when called from the
74  # Python filter command, do not cease filter operations, just set
75  # enabled to False.
76  return getattr(filter_item, "enabled", False)
77 
78 def set_enabled(filter_item, state):
79  """ Internal Worker function to set the frame-filter's enabled
80  state.
81 
82  Arguments:
83  filter_item: An object conforming to the frame filter
84  interface.
85  state: True or False, depending on desired state.
86  """
87 
88  filter_item.enabled = state
89 
90 def return_list(name):
91  """ Internal Worker function to return the frame filter
92  dictionary, depending on the name supplied as an argument. If the
93  name is not "all", "global" or "progspace", it is assumed to name
94  an object-file.
95 
96  Arguments:
97  name: The name of the list, as specified by GDB user commands.
98 
99  Returns:
100  A dictionary object for a single specified dictionary, or a
101  list containing all the items for "all"
102 
103  Raises:
104  gdb.GdbError: A dictionary of that name cannot be found.
105  """
106 
107  # If all dictionaries are wanted in the case of "all" we
108  # cannot return a combined dictionary as keys() may clash in
109  # between different dictionaries. As we just want all the frame
110  # filters to enable/disable them all, just return the combined
111  # items() as a chained iterator of dictionary values.
112  if name == "all":
113  glob = gdb.frame_filters.values()
114  prog = gdb.current_progspace().frame_filters.values()
115  return_iter = itertools.chain(glob, prog)
116  for objfile in gdb.objfiles():
117  return_iter = itertools.chain(return_iter, objfile.frame_filters.values())
118 
119  return return_iter
120 
121  if name == "global":
122  return gdb.frame_filters
123  else:
124  if name == "progspace":
125  cp = gdb.current_progspace()
126  return cp.frame_filters
127  else:
128  for objfile in gdb.objfiles():
129  if name == objfile.filename:
130  return objfile.frame_filters
131 
132  msg = "Cannot find frame-filter dictionary for '" + name + "'"
133  raise gdb.GdbError(msg)
134 
136  """ Internal Worker function to merge all known frame-filter
137  lists, prune any filters with the state set to "disabled", and
138  sort the list on the frame-filter's "priority" attribute.
139 
140  Returns:
141  sorted_list: A sorted, pruned list of frame filters to
142  execute.
143  """
144 
145  all_filters = return_list("all")
146  sorted_frame_filters = sorted(all_filters, key = get_priority,
147  reverse = True)
148 
149  sorted_frame_filters = filter(get_enabled,
150  sorted_frame_filters)
151 
152  return sorted_frame_filters
153 
154 def execute_frame_filters(frame, frame_low, frame_high):
155  """ Internal function called from GDB that will execute the chain
156  of frame filters. Each filter is executed in priority order.
157  After the execution completes, slice the iterator to frame_low -
158  frame_high range.
159 
160  Arguments:
161  frame: The initial frame.
162 
163  frame_low: The low range of the slice. If this is a negative
164  integer then it indicates a backward slice (ie bt -4) which
165  counts backward from the last frame in the backtrace.
166 
167  frame_high: The high range of the slice. If this is -1 then
168  it indicates all frames until the end of the stack from
169  frame_low.
170 
171  Returns:
172  frame_iterator: The sliced iterator after all frame
173  filters have had a change to execute, or None if no frame
174  filters are registered.
175  """
176 
177  # Get a sorted list of frame filters.
178  sorted_list = list(_sort_list())
179 
180  # Check to see if there are any frame-filters. If not, just
181  # return None and let default backtrace printing occur.
182  if len(sorted_list) == 0:
183  return None
184 
185  frame_iterator = FrameIterator(frame)
186 
187  # Apply a basic frame decorator to all gdb.Frames. This unifies
188  # the interface. Python 3.x moved the itertools.imap
189  # functionality to map(), so check if it is available.
190  if hasattr(itertools,"imap"):
191  frame_iterator = itertools.imap(FrameDecorator, frame_iterator)
192  else:
193  frame_iterator = map(FrameDecorator, frame_iterator)
194 
195  for ff in sorted_list:
196  frame_iterator = ff.filter(frame_iterator)
197 
198  # Slicing
199 
200  # Is this a slice from the end of the backtrace, ie bt -2?
201  if frame_low < 0:
202  count = 0
203  slice_length = abs(frame_low)
204  # We cannot use MAXLEN argument for deque as it is 2.6 onwards
205  # and some GDB versions might be < 2.6.
206  sliced = collections.deque()
207 
208  for frame_item in frame_iterator:
209  if count >= slice_length:
210  sliced.popleft();
211  count = count + 1
212  sliced.append(frame_item)
213 
214  return iter(sliced)
215 
216  # -1 for frame_high means until the end of the backtrace. Set to
217  # None if that is the case, to indicate to itertools.islice to
218  # slice to the end of the iterator.
219  if frame_high == -1:
220  frame_high = None
221  else:
222  # As frames start from 0, add one to frame_high so islice
223  # correctly finds the end
224  frame_high = frame_high + 1;
225 
226  sliced = itertools.islice(frame_iterator, frame_low, frame_high)
227 
228  return sliced
def set_enabled(filter_item, state)
Definition: frames.py:78
def set_priority(filter_item, priority)
Definition: frames.py:45
def return_list(name)
Definition: frames.py:90
def execute_frame_filters(frame, frame_low, frame_high)
Definition: frames.py:154
def get_enabled(filter_item)
Definition: frames.py:56
def get_priority(filter_item)
Definition: frames.py:25
def _sort_list()
Definition: frames.py:135
const ULONGEST const LONGEST len
Definition: target.h:309