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
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
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."""
import gdb
from gdb.FrameIterator import FrameIterator
-from gdb.FrameDecorator import FrameDecorator
+from gdb.FrameDecorator import FrameDecorator, DAPFrameDecorator
import itertools
import collections
# 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)
"""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.