1 # Frame-filter commands.
2 # Copyright (C) 2013-2016 Free Software Foundation, Inc.
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.
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.
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/>.
17 """Internal functions for working with frame-filters."""
20 from gdb
.FrameIterator
import FrameIterator
21 from gdb
.FrameDecorator
import FrameDecorator
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).
34 filter_item: An object conforming to the frame filter
38 The priority of the frame filter from the "priority"
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)
45 def set_priority(filter_item
, priority
):
46 """ Internal worker function to set the frame-filter's priority.
49 filter_item: An object conforming to the frame filter
51 priority: The priority to assign as an integer.
54 filter_item
.priority
= priority
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).
65 filter_item: An object conforming to the frame filter
69 The enabled state of the frame filter from the "enabled"
73 # If the filter class is badly implemented when called from the
74 # Python filter command, do not cease filter operations, just set
76 return getattr(filter_item
, "enabled", False)
78 def set_enabled(filter_item
, state
):
79 """ Internal Worker function to set the frame-filter's enabled
83 filter_item: An object conforming to the frame filter
85 state: True or False, depending on desired state.
88 filter_item
.enabled
= state
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
97 name: The name of the list, as specified by GDB user commands.
100 A dictionary object for a single specified dictionary, or a
101 list containing all the items for "all"
104 gdb.GdbError: A dictionary of that name cannot be found.
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.
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())
122 return gdb
.frame_filters
124 if name
== "progspace":
125 cp
= gdb
.current_progspace()
126 return cp
.frame_filters
128 for objfile
in gdb
.objfiles():
129 if name
== objfile
.filename
:
130 return objfile
.frame_filters
132 msg
= "Cannot find frame-filter dictionary for '" + name
+ "'"
133 raise gdb
.GdbError(msg
)
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.
141 sorted_list: A sorted, pruned list of frame filters to
145 all_filters
= return_list("all")
146 sorted_frame_filters
= sorted(all_filters
, key
= get_priority
,
149 sorted_frame_filters
= filter(get_enabled
,
150 sorted_frame_filters
)
152 return sorted_frame_filters
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 -
161 frame: The initial frame.
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.
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
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.
177 # Get a sorted list of frame filters.
178 sorted_list
= list(_sort_list())
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:
185 frame_iterator
= FrameIterator(frame
)
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
)
193 frame_iterator
= map(FrameDecorator
, frame_iterator
)
195 for ff
in sorted_list
:
196 frame_iterator
= ff
.filter(frame_iterator
)
200 # Is this a slice from the end of the backtrace, ie bt -2?
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()
208 for frame_item
in frame_iterator
:
209 if count
>= slice_length
:
212 sliced
.append(frame_item
)
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.
222 # As frames start from 0, add one to frame_high so islice
223 # correctly finds the end
224 frame_high
= frame_high
+ 1;
226 sliced
= itertools
.islice(frame_iterator
, frame_low
, frame_high
)
This page took 0.038925 seconds and 4 git commands to generate.