GDB (API)
/home/stan/gdb/linux/gdb/data-directory/python/gdb/frames.py
Go to the documentation of this file.
00001 # Frame-filter commands.
00002 # Copyright (C) 2013 Free Software Foundation, Inc.
00003 
00004 # This program is free software; you can redistribute it and/or modify
00005 # it under the terms of the GNU General Public License as published by
00006 # the Free Software Foundation; either version 3 of the License, or
00007 # (at your option) any later version.
00008 #
00009 # This program is distributed in the hope that it will be useful,
00010 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 # GNU General Public License for more details.
00013 #
00014 # You should have received a copy of the GNU General Public License
00015 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 """Internal functions for working with frame-filters."""
00018 
00019 import gdb
00020 from gdb.FrameIterator import FrameIterator
00021 from gdb.FrameDecorator import FrameDecorator
00022 import itertools
00023 import collections
00024 
00025 def get_priority(filter_item):
00026     """ Internal worker function to return the frame-filter's priority
00027     from a frame filter object.  This is a fail free function as it is
00028     used in sorting and filtering.  If a badly implemented frame
00029     filter does not implement the priority attribute, return zero
00030     (otherwise sorting/filtering will fail and prevent other frame
00031     filters from executing).
00032 
00033     Arguments:
00034         filter_item: An object conforming to the frame filter
00035                      interface.
00036 
00037     Returns:
00038         The priority of the frame filter from the "priority"
00039         attribute, or zero.
00040     """
00041     # Do not fail here, as the sort will fail.  If a filter has not
00042     # (incorrectly) set a priority, set it to zero.
00043     return getattr(filter_item, "priority", 0)
00044 
00045 def set_priority(filter_item, priority):
00046     """ Internal worker function to set the frame-filter's priority.
00047 
00048     Arguments:
00049         filter_item: An object conforming to the frame filter
00050                      interface.
00051         priority: The priority to assign as an integer.
00052     """
00053 
00054     filter_item.priority = priority
00055 
00056 def get_enabled(filter_item):
00057     """ Internal worker function to return a filter's enabled state
00058     from a frame filter object.  This is a fail free function as it is
00059     used in sorting and filtering.  If a badly implemented frame
00060     filter does not implement the enabled attribute, return False
00061     (otherwise sorting/filtering will fail and prevent other frame
00062     filters from executing).
00063 
00064     Arguments:
00065         filter_item: An object conforming to the frame filter
00066                      interface.
00067 
00068     Returns:
00069         The enabled state of the frame filter from the "enabled"
00070         attribute, or False.
00071     """
00072 
00073     # If the filter class is badly implemented when called from the
00074     # Python filter command, do not cease filter operations, just set
00075     # enabled to False.
00076     return getattr(filter_item, "enabled", False)
00077 
00078 def set_enabled(filter_item, state):
00079     """ Internal Worker function to set the frame-filter's enabled
00080     state.
00081 
00082     Arguments:
00083         filter_item: An object conforming to the frame filter
00084                      interface.
00085         state: True or False, depending on desired state.
00086     """
00087 
00088     filter_item.enabled = state
00089 
00090 def return_list(name):
00091     """ Internal Worker function to return the frame filter
00092     dictionary, depending on the name supplied as an argument.  If the
00093     name is not "all", "global" or "progspace", it is assumed to name
00094     an object-file.
00095 
00096     Arguments:
00097         name: The name of the list, as specified by GDB user commands.
00098 
00099     Returns:
00100         A dictionary object for a single specified dictionary, or a
00101         list containing all the items for "all"
00102 
00103     Raises:
00104         gdb.GdbError:  A dictionary of that name cannot be found.
00105     """
00106 
00107     # If all dictionaries are wanted in the case of "all" we
00108     # cannot return a combined dictionary as keys() may clash in
00109     # between different dictionaries.  As we just want all the frame
00110     # filters to enable/disable them all, just return the combined
00111     # items() as a chained iterator of dictionary values.
00112     if name == "all":
00113         glob = gdb.frame_filters.values()
00114         prog = gdb.current_progspace().frame_filters.values()
00115         return_iter = itertools.chain(glob, prog)
00116         for objfile in gdb.objfiles():
00117             return_iter = itertools.chain(return_iter, objfile.frame_filters.values())
00118 
00119         return return_iter
00120 
00121     if name == "global":
00122         return gdb.frame_filters
00123     else:
00124         if name == "progspace":
00125             cp = gdb.current_progspace()
00126             return cp.frame_filters
00127         else:
00128             for objfile in gdb.objfiles():
00129                 if name == objfile.filename:
00130                     return objfile.frame_filters
00131 
00132     msg = "Cannot find frame-filter dictionary for '" + name + "'"
00133     raise gdb.GdbError(msg)
00134 
00135 def _sort_list():
00136     """ Internal Worker function to merge all known frame-filter
00137     lists, prune any filters with the state set to "disabled", and
00138     sort the list on the frame-filter's "priority" attribute.
00139 
00140     Returns:
00141         sorted_list: A sorted, pruned list of frame filters to
00142                      execute.
00143     """
00144 
00145     all_filters = return_list("all")
00146     sorted_frame_filters = sorted(all_filters, key = get_priority,
00147                                   reverse = True)
00148 
00149     sorted_frame_filters = filter(get_enabled,
00150                                   sorted_frame_filters)
00151 
00152     return sorted_frame_filters
00153 
00154 def execute_frame_filters(frame, frame_low, frame_high):
00155     """ Internal function called from GDB that will execute the chain
00156     of frame filters.  Each filter is executed in priority order.
00157     After the execution completes, slice the iterator to frame_low -
00158     frame_high range.
00159 
00160     Arguments:
00161         frame: The initial frame.
00162 
00163         frame_low: The low range of the slice.  If this is a negative
00164         integer then it indicates a backward slice (ie bt -4) which
00165         counts backward from the last frame in the backtrace.
00166 
00167         frame_high: The high range of the slice.  If this is -1 then
00168         it indicates all frames until the end of the stack from
00169         frame_low.
00170 
00171     Returns:
00172         frame_iterator: The sliced iterator after all frame
00173         filters have had a change to execute, or None if no frame
00174         filters are registered.
00175     """
00176 
00177     # Get a sorted list of frame filters.
00178     sorted_list = list(_sort_list())
00179 
00180     # Check to see if there are any frame-filters.  If not, just
00181     # return None and let default backtrace printing occur.
00182     if len(sorted_list) == 0:
00183         return None
00184 
00185     frame_iterator = FrameIterator(frame)
00186 
00187     # Apply a basic frame decorator to all gdb.Frames.  This unifies
00188     # the interface.  Python 3.x moved the itertools.imap
00189     # functionality to map(), so check if it is available.
00190     if hasattr(itertools,"imap"):
00191         frame_iterator = itertools.imap(FrameDecorator, frame_iterator)
00192     else:
00193         frame_iterator = map(FrameDecorator, frame_iterator)
00194 
00195     for ff in sorted_list:
00196         frame_iterator = ff.filter(frame_iterator)
00197 
00198     # Slicing
00199 
00200     # Is this a slice from the end of the backtrace, ie bt -2?
00201     if frame_low < 0:
00202         count = 0
00203         slice_length = abs(frame_low)
00204         # We cannot use MAXLEN argument for deque as it is 2.6 onwards
00205         # and some GDB versions might be < 2.6.
00206         sliced = collections.deque()
00207 
00208         for frame_item in frame_iterator:
00209             if count >= slice_length:
00210                 sliced.popleft();
00211             count = count + 1
00212             sliced.append(frame_item)
00213 
00214         return iter(sliced)
00215 
00216     # -1 for frame_high means until the end of the backtrace.  Set to
00217     # None if that is the case, to indicate to itertools.islice to
00218     # slice to the end of the iterator.
00219     if frame_high == -1:
00220         frame_high = None
00221     else:
00222         # As frames start from 0, add one to frame_high so islice
00223         # correctly finds the end
00224         frame_high = frame_high + 1;
00225 
00226     sliced = itertools.islice(frame_iterator, frame_low, frame_high)
00227 
00228     return sliced
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines