diff --git a/gdb/python/lib/gdb/FrameDecorator.py b/gdb/python/lib/gdb/FrameDecorator.py
index c4a7806e434..22d5fa4d0a9 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..104ff4bb203 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
 
@@ -172,7 +172,11 @@ def _frame_iterator(frame, frame_low, frame_high, always):
 
     # Apply a basic frame decorator to all gdb.Frames.  This unifies
     # the interface.
-    frame_iterator = map(FrameDecorator, frame_iterator)
+    if always:
+        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.
