diff --git a/gobject/gobject.py b/gobject/gobject.py
index 48a9309..9e430de 100644
--- a/gobject/gobject.py
+++ b/gobject/gobject.py
@@ -2,19 +2,29 @@ import os.path
 import gdb
 import glib
 import sys
+import itertools
 
 if sys.version_info[0] >= 3:
     long = int
 
+# Fedora shipped a "gdb.backtrace" module for a while; but when
+# upstreamed this was heavily modified.  gdb.FrameDecorator is the
+# newer, preferred module to use.
 try:
-    import gdb.backtrace
-    import gdb.command.backtrace
-except ImportError:
-    print(os.path.basename(__file__) + ": gdb was not built with "
-          "custom backtrace support, disabling.")
+    import gdb.FrameDecorator
+    HAVE_GDB_FRAMEDECORATOR = True
     HAVE_GDB_BACKTRACE = 0
-else:
-    HAVE_GDB_BACKTRACE = 1
+except ImportError:
+    HAVE_GDB_FRAMEDECORATOR = False
+    try:
+        import gdb.backtrace
+        import gdb.command.backtrace
+    except ImportError:
+        print(os.path.basename(__file__) + ": gdb was not built with "
+              "custom backtrace support, disabling.")
+        HAVE_GDB_BACKTRACE = 0
+    else:
+        HAVE_GDB_BACKTRACE = 1
 
 # This is not quite right, as local vars may override symname
 def read_global_var (symname):
@@ -119,8 +129,37 @@ class DummyFrame:
     def __getattr__ (self, name):
         return getattr (self.frame, name)
 
-class SignalFrame:
+if HAVE_GDB_FRAMEDECORATOR:
+    FrameDecorator = gdb.FrameDecorator.FrameDecorator
+
+    # Get the name given a FrameDecorator.
+    def frame_name(frame):
+        return str(frame.function())
+
+    # Get a variable from a FrameDecorator.
+    def frame_var(frame, var):
+        return frame.inferior_frame().read_var(var)
+
+else:
+    class FrameDecorator:
+        def __init__(self, ignore):
+            pass
+
+        def __getattr__ (self, name):
+            # self.frame is set in the derived class.
+            return getattr (self.frame, name)
+
+    # Get the name given a gdb.Frame.
+    def frame_name(frame):
+        return frame.name()
+
+    # Get a variable from a gdb.Frame.
+    def frame_var(frame, var):
+        return frame.read_var(var)
+
+class SignalFrame(FrameDecorator):
     def __init__ (self, frames):
+        FrameDecorator.__init__(self, frames[-1])
         self.frame = frames[-1]
         self.frames = frames
 
@@ -129,7 +168,7 @@ class SignalFrame:
 
     def read_var (self, frame, name, array = None):
         try:
-            v = frame.read_var (name)
+            v = frame_var (frame, name)
             if v == None or v.is_optimized_out:
                 return None
             if array != None:
@@ -140,7 +179,7 @@ class SignalFrame:
 
     def read_object (self, frame, name, array = None):
         try:
-            v = frame.read_var (name)
+            v = frame_var (frame, name)
             if v == None or v.is_optimized_out:
                 return None
             v = v.cast (gdb.lookup_type("GObject").pointer())
@@ -161,7 +200,7 @@ class SignalFrame:
         if len(array) == 0:
             return "???"
         else:
-            return ' or '.join(set(array))
+            return ' or '.join(set(itertools.imap(str, array)))
 
     def get_detailed_signal_from_frame(self, frame, signal):
         detail = self.read_var (frame, "detail")
@@ -171,12 +210,12 @@ class SignalFrame:
         else:
             return detail
 
-    def describe (self, stream, full):
+    def function (self):
         instances = []
         signals = []
 
         for frame in self.frames:
-            name = frame.name()
+            name = frame_name(frame)
             if name == "signal_emit_unlocked_R":
                 self.read_object (frame, "instance", instances)
                 node = self.read_var (frame, "node")
@@ -212,12 +251,15 @@ class SignalFrame:
         instance = self.or_join_array (instances)
         signal = self.or_join_array (signals)
 
-        stream.write (" <emit signal %s on instance %s>\n" %  (signal, instance))
+        return "<emit signal %s on instance %s>" %  (signal, instance)
 
-    def __getattr__ (self, name):
-        return getattr (self.frame, name)
+    def elided (self):
+        return self.frames[0:-1]
+
+    def describe (self, stream, full):
+        stream.write (" " + self.function () + "\n")
 
-class GFrameFilter:
+class GFrameDecorator:
     def __init__ (self, iter):
         self.queue = []
         self.iter = iter
@@ -235,7 +277,7 @@ class GFrameFilter:
 
     def find_signal_emission (self):
         for i in range (min (len(self.queue), 3)):
-            if self.queue[i].name() == "signal_emit_unlocked_R":
+            if frame_name(self.queue[i]) == "signal_emit_unlocked_R":
                 return i
         return -1
 
@@ -253,36 +295,47 @@ class GFrameFilter:
             while True:
                 if start == 0:
                     break
-                prev_name = self.queue[start-1].name()
+                prev_name = frame_name(self.queue[start-1])
                 if prev_name.find("_marshal_") or prev_name == "g_closure_invoke":
                     start = start - 1
                 else:
                     break
             end = emission + 1
             while end < len(self.queue):
-                if self.queue[end].name() in ["g_signal_emitv",
-                                              "g_signal_emit_valist",
-                                              "g_signal_emit",
-                                              "g_signal_emit_by_name"]:
+                if frame_name(self.queue[end]) in ["g_signal_emitv",
+                                                   "g_signal_emit_valist",
+                                                   "g_signal_emit",
+                                                   "g_signal_emit_by_name"]:
                     end = end + 1
                 else:
                     break
 
             signal_frames = self.queue[start:end]
             new_frames = []
-            for i in range(len(signal_frames)-1):
-                new_frames.append(DummyFrame(signal_frames[i]))
+            if not HAVE_GDB_FRAMEDECORATOR:
+                for i in range(len(signal_frames)-1):
+                    new_frames.append(DummyFrame(signal_frames[i]))
             new_frames.append(SignalFrame(signal_frames))
 
             self.queue[start:end] = new_frames
 
         return self.queue.pop(0)
 
+class GFrameFilter(object):
+    name = 'glib'
+    enabled = True
+    priority = 100
+
+    def filter(self, iterator):
+        return GFrameDecorator(iterator)
 
 def register (obj):
     if obj == None:
         obj = gdb
 
-    if HAVE_GDB_BACKTRACE:
-        gdb.backtrace.push_frame_filter (GFrameFilter)
+    if HAVE_GDB_FRAMEDECORATOR:
+        filter = GFrameFilter()
+        obj.frame_filters[filter.name] = filter
+    elif HAVE_GDB_BACKTRACE:
+        gdb.backtrace.push_frame_filter (GFrameDecorator)
     obj.pretty_printers.append(pretty_printer_lookup)
