diff --git a/gdb/python/lib/gdb/FrameDecorator.py b/gdb/python/lib/gdb/FrameDecorator.py index c4a7806e434..aa9a2201bec 100644 --- a/gdb/python/lib/gdb/FrameDecorator.py +++ b/gdb/python/lib/gdb/FrameDecorator.py @@ -16,34 +16,8 @@ import gdb -class FrameDecorator(object): - """Basic implementation of a Frame Decorator""" - - """ This base frame decorator decorates a frame or another frame - decorator, and provides convenience methods. If this object is - wrapping a frame decorator, defer to that wrapped object's method - if it has one. This allows for frame decorators that have - sub-classed FrameDecorator object, but also wrap other frame - decorators on the same frame to correctly execute. - - E.g - - If the result of frame filters running means we have one gdb.Frame - wrapped by multiple frame decorators, all sub-classed from - FrameDecorator, the resulting hierarchy will be: - - Decorator1 - -- (wraps) Decorator2 - -- (wraps) FrameDecorator - -- (wraps) gdb.Frame - - In this case we have two frame decorators, both of which are - sub-classed from FrameDecorator. If Decorator1 just overrides the - 'function' method, then all of the other methods are carried out - by the super-class FrameDecorator. But Decorator2 may have - overriden other methods, so FrameDecorator will look at the - 'base' parameter and defer to that class's methods. And so on, - down the chain.""" +class _FrameDecoratorBase(object): + """Base class of frame decorators.""" # 'base' can refer to a gdb.Frame or another frame decorator. In # the latter case, the child class will have called the super @@ -122,22 +96,6 @@ class FrameDecorator(object): frame = self.inferior_frame() return frame.pc() - def filename(self): - """Return the filename associated with this frame, detecting - and returning the appropriate library name is this is a shared - library.""" - - if hasattr(self._base, "filename"): - return self._base.filename() - - frame = self.inferior_frame() - sal = frame.find_sal() - if not sal.symtab or not sal.symtab.filename: - pc = frame.pc() - return gdb.solib_name(pc) - else: - return sal.symtab.filename - def frame_args(self): """Return an iterable of frame arguments for this frame, if any. The iterable object contains objects conforming with the @@ -198,6 +156,71 @@ class FrameDecorator(object): return self._base +class FrameDecorator(_FrameDecoratorBase): + """Basic implementation of a Frame Decorator + + This base frame decorator decorates a frame or another frame + decorator, and provides convenience methods. If this object is + wrapping a frame decorator, defer to that wrapped object's method + if it has one. This allows for frame decorators that have + sub-classed FrameDecorator object, but also wrap other frame + decorators on the same frame to correctly execute. + + E.g + + If the result of frame filters running means we have one gdb.Frame + wrapped by multiple frame decorators, all sub-classed from + FrameDecorator, the resulting hierarchy will be: + + Decorator1 + -- (wraps) Decorator2 + -- (wraps) FrameDecorator + -- (wraps) gdb.Frame + + In this case we have two frame decorators, both of which are + sub-classed from FrameDecorator. If Decorator1 just overrides the + 'function' method, then all of the other methods are carried out + by the super-class FrameDecorator. But Decorator2 may have + overriden other methods, so FrameDecorator will look at the + 'base' parameter and defer to that class's methods. And so on, + down the chain.""" + + def filename(self): + """Return the filename associated with this frame, detecting + and returning the appropriate library name is this is a shared + library.""" + + if hasattr(self._base, "filename"): + return self._base.filename() + + frame = self.inferior_frame() + sal = frame.find_sal() + if not sal.symtab or not sal.symtab.filename: + pc = frame.pc() + return gdb.solib_name(pc) + else: + return sal.symtab.filename + + +class DAPFrameDecorator(_FrameDecoratorBase): + """Like FrameDecorator, but has slightly different results + for the "filename" method.""" + + def filename(self): + """Return the filename associated with this frame, detecting + and returning the appropriate library name is this is a shared + library.""" + + if hasattr(self._base, "filename"): + return self._base.filename() + + frame = self.inferior_frame() + sal = frame.find_sal() + if sal.symtab is not None: + return sal.symtab.fullname() + return None + + class SymValueWrapper(object): """A container class conforming to the Symbol/Value interface which holds frame locals or frame arguments.""" diff --git a/gdb/python/lib/gdb/frames.py b/gdb/python/lib/gdb/frames.py index cff3ba07704..833941e8079 100644 --- a/gdb/python/lib/gdb/frames.py +++ b/gdb/python/lib/gdb/frames.py @@ -18,7 +18,7 @@ import gdb from gdb.FrameIterator import FrameIterator -from gdb.FrameDecorator import FrameDecorator +from gdb.FrameDecorator import FrameDecorator, DAPFrameDecorator import itertools import collections @@ -157,22 +157,26 @@ def _sort_list(): # Internal function that implements frame_iterator and -# execute_frame_filters. If ALWAYS is True, then this will always -# return an iterator. -def _frame_iterator(frame, frame_low, frame_high, always): +# execute_frame_filters. If DAP_SEMANTICS is True, then this will +# always return an iterator and will wrap frames in DAPFrameDecorator. +def _frame_iterator(frame, frame_low, frame_high, dap_semantics): # Get a sorted list of frame filters. sorted_list = list(_sort_list()) # Check to see if there are any frame-filters. If not, just # return None and let default backtrace printing occur. - if not always and len(sorted_list) == 0: + if not dap_semantics and len(sorted_list) == 0: return None frame_iterator = FrameIterator(frame) # Apply a basic frame decorator to all gdb.Frames. This unifies # the interface. - frame_iterator = map(FrameDecorator, frame_iterator) + if dap_semantics: + decorator = DAPFrameDecorator + else: + decorator = FrameDecorator + frame_iterator = map(decorator, frame_iterator) for ff in sorted_list: frame_iterator = ff.filter(frame_iterator) @@ -214,7 +218,11 @@ def frame_iterator(frame, frame_low, frame_high): """Helper function that will execute the chain of frame filters. Each filter is executed in priority order. After the execution completes, slice the iterator to frame_low - frame_high range. An - iterator is always returned. + iterator is always returned. The iterator will always yield + frame decorator objects, but note that these decorators have + slightly different semantics from the ordinary ones: they will + always return a fully-qualified 'filename' (if possible) and will + never substitute the objfile name. Arguments: frame: The initial frame.