diff --git a/.bzrignore b/.bzrignore
index 75db628..86315f6 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -14,6 +14,7 @@
 pyconfig.h
 libpython*.a
 python.exe
+python-gdb.py
 reflog.txt
 tags
 TAGS
diff --git a/.hgignore b/.hgignore
index 021fef1..1980c7b 100644
--- a/.hgignore
+++ b/.hgignore
@@ -30,6 +30,7 @@
 Modules/config.c
 Parser/pgen
 core
+python-gdb.py
 
 syntax: glob
 libpython*.a
diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py
new file mode 100644
index 0000000..fe8682a
--- /dev/null
+++ b/Lib/test/test_gdb.py
@@ -0,0 +1,658 @@
+# Verify that gdb can pretty-print the various PyObject* types
+#
+# The code for testing gdb was adapted from similar work in Unladen Swallow's
+# Lib/test/test_jit_gdb.py
+
+import os
+import re
+import subprocess
+import sys
+import unittest
+
+from test.test_support import run_unittest
+
+try:
+    gdb_version, _ = subprocess.Popen(["gdb", "--version"],
+                                      stdout=subprocess.PIPE).communicate()
+except OSError:
+    # This is what "no gdb" looks like.  There may, however, be other
+    # errors that manifest this way too.
+    raise unittest.SkipTest("Couldn't find gdb on the path")
+gdb_version_number = re.search(r"^GNU gdb [^\d]*(\d+)\.", gdb_version)
+if int(gdb_version_number.group(1)) < 7:
+    raise unittest.SkipTest("gdb versions before 7.0 didn't support python embedding"
+                            " Saw:\n" + gdb_version)
+
+# Verify that "gdb" was built with the embedded python support enabled:
+cmd = "--eval-command=python import sys; print sys.version_info"
+p = subprocess.Popen(["gdb", "--batch", cmd],
+                     stdout=subprocess.PIPE)
+gdbpy_version, _ = p.communicate()
+if gdbpy_version == '':
+    raise unittest.SkipTest("gdb not built with embedded python support")
+
+
+class DebuggerTests(unittest.TestCase):
+
+    """Test that the debugger can debug Python."""
+
+    def run_gdb(self, *args):
+        """Runs gdb with the command line given by *args.
+
+        Returns its stdout, stderr
+        """
+        out, err = subprocess.Popen(
+            args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+            ).communicate()
+        return out, err
+
+    def get_stack_trace(self, source=None, script=None,
+                        breakpoint='PyObject_Print',
+                        cmds_after_breakpoint=None,
+                        import_site=False):
+        '''
+        Run 'python -c SOURCE' under gdb with a breakpoint.
+
+        Support injecting commands after the breakpoint is reached
+
+        Returns the stdout from gdb
+
+        cmds_after_breakpoint: if provided, a list of strings: gdb commands
+        '''
+        # We use "set breakpoint pending yes" to avoid blocking with a:
+        #   Function "foo" not defined.
+        #   Make breakpoint pending on future shared library load? (y or [n])
+        # error, which typically happens python is dynamically linked (the
+        # breakpoints of interest are to be found in the shared library)
+        # When this happens, we still get:
+        #   Function "PyObject_Print" not defined.
+        # emitted to stderr each time, alas.
+
+        # Initially I had "--eval-command=continue" here, but removed it to
+        # avoid repeated print breakpoints when traversing hierarchical data
+        # structures
+
+        # Generate a list of commands in gdb's language:
+        commands = ['set breakpoint pending yes',
+                    'break %s' % breakpoint,
+                    'run']
+        if cmds_after_breakpoint:
+            commands += cmds_after_breakpoint
+        else:
+            commands += ['backtrace']
+
+        # print commands
+
+        # Use "commands" to generate the arguments with which to invoke "gdb":
+        args = ["gdb", "--batch"]
+        args += ['--eval-command=%s' % cmd for cmd in commands]
+        args += ["--args",
+                 sys.executable]
+
+        if not import_site:
+            # -S suppresses the default 'import site'
+            args += ["-S"]
+
+        if source:
+            args += ["-c", source]
+        elif script:
+            args += [script]
+
+        # print args
+        # print ' '.join(args)
+
+        # Use "args" to invoke gdb, capturing stdout, stderr:
+        out, err = self.run_gdb(*args)
+
+        # Ignore some noise on stderr due to the pending breakpoint:
+        err = err.replace('Function "%s" not defined.\n' % breakpoint, '')
+
+        # Ensure no unexpected error messages:
+        self.assertEquals(err, '')
+
+        return out
+
+    def get_gdb_repr(self, source,
+                     cmds_after_breakpoint=None,
+                     import_site=False):
+        # Given an input python source representation of data,
+        # run "python -c'print DATA'" under gdb with a breakpoint on
+        # PyObject_Print and scrape out gdb's representation of the "op"
+        # parameter, and verify that the gdb displays the same string
+        #
+        # For a nested structure, the first time we hit the breakpoint will
+        # give us the top-level structure
+        gdb_output = self.get_stack_trace(source, breakpoint='PyObject_Print',
+                                          cmds_after_breakpoint=cmds_after_breakpoint,
+                                          import_site=import_site)
+        m = re.match('.*#0  PyObject_Print \(op\=(.*?), fp=.*\).*',
+                     gdb_output, re.DOTALL)
+        #print m.groups()
+        return m.group(1), gdb_output
+
+    def assertEndsWith(self, actual, exp_end):
+        '''Ensure that the given "actual" string ends with "exp_end"'''
+        self.assert_(actual.endswith(exp_end),
+                     msg='%r did not end with %r' % (actual, exp_end))
+
+    def assertMultilineMatches(self, actual, pattern):
+        m = re.match(pattern, actual, re.DOTALL)
+        self.assert_(m,
+                     msg='%r did not match %r' % (actual, pattern))
+
+class PrettyPrintTests(DebuggerTests):
+    def test_getting_backtrace(self):
+        gdb_output = self.get_stack_trace('print 42')
+        self.assertTrue('PyObject_Print' in gdb_output)
+
+    def assertGdbRepr(self, val, cmds_after_breakpoint=None):
+        # Ensure that gdb's rendering of the value in a debugged process
+        # matches repr(value) in this process:
+        gdb_repr, gdb_output = self.get_gdb_repr('print ' + repr(val),
+                                                 cmds_after_breakpoint)
+        self.assertEquals(gdb_repr, repr(val), gdb_output)
+
+    def test_int(self):
+        'Verify the pretty-printing of various "int" values'
+        self.assertGdbRepr(42)
+        self.assertGdbRepr(0)
+        self.assertGdbRepr(-7)
+        self.assertGdbRepr(sys.maxint)
+        self.assertGdbRepr(-sys.maxint)
+
+    def test_long(self):
+        'Verify the pretty-printing of various "long" values'
+        self.assertGdbRepr(0L)
+        self.assertGdbRepr(1000000000000L)
+        self.assertGdbRepr(-1L)
+        self.assertGdbRepr(-1000000000000000L)
+
+    def test_singletons(self):
+        'Verify the pretty-printing of True, False and None'
+        self.assertGdbRepr(True)
+        self.assertGdbRepr(False)
+        self.assertGdbRepr(None)
+
+    def test_dicts(self):
+        'Verify the pretty-printing of dictionaries'
+        self.assertGdbRepr({})
+        self.assertGdbRepr({'foo': 'bar'})
+        self.assertGdbRepr({'foo': 'bar', 'douglas':42})
+
+    def test_lists(self):
+        'Verify the pretty-printing of lists'
+        self.assertGdbRepr([])
+        self.assertGdbRepr(range(5))
+
+    def test_strings(self):
+        'Verify the pretty-printing of strings'
+        self.assertGdbRepr('')
+        self.assertGdbRepr('And now for something hopefully the same')
+        self.assertGdbRepr('string with embedded NUL here \0 and then some more text')
+        self.assertGdbRepr('this is byte 255:\xff and byte 128:\x80')
+
+    def test_tuples(self):
+        'Verify the pretty-printing of tuples'
+        self.assertGdbRepr(tuple())
+        self.assertGdbRepr((1,))
+        self.assertGdbRepr(('foo', 'bar', 'baz'))
+
+    def test_unicode(self):
+        'Verify the pretty-printing of unicode values'
+        # Test the empty unicode string:
+        self.assertGdbRepr(u'')
+
+        self.assertGdbRepr(u'hello world')
+
+        # Test printing a single character:
+        #    U+2620 SKULL AND CROSSBONES
+        self.assertGdbRepr(u'\u2620')
+
+        # Test printing a Japanese unicode string
+        # (I believe this reads "mojibake", using 3 characters from the CJK
+        # Unified Ideographs area, followed by U+3051 HIRAGANA LETTER KE)
+        self.assertGdbRepr(u'\u6587\u5b57\u5316\u3051')
+
+        # Test a character outside the BMP:
+        #    U+1D121 MUSICAL SYMBOL C CLEF
+        # This is:
+        # UTF-8: 0xF0 0x9D 0x84 0xA1
+        # UTF-16: 0xD834 0xDD21
+        try:
+            # This will only work on wide-unicode builds:
+            self.assertGdbRepr(unichr(0x1D121))
+        except ValueError, e:
+            if e.message != 'unichr() arg not in range(0x10000) (narrow Python build)':
+                raise e
+
+    def test_sets(self):
+        'Verify the pretty-printing of sets'
+        self.assertGdbRepr(set())
+        self.assertGdbRepr(set(['a', 'b']))
+        self.assertGdbRepr(set([4, 5, 6]))
+
+        # Ensure that we handled sets containing the "dummy" key value,
+        # which happens on deletion:
+        gdb_repr, gdb_output = self.get_gdb_repr('''s = set(['a','b'])
+s.pop()
+print s''')
+        self.assertEquals(gdb_repr, "set(['b'])")
+
+    def test_frozensets(self):
+        'Verify the pretty-printing of frozensets'
+        self.assertGdbRepr(frozenset())
+        self.assertGdbRepr(frozenset(['a', 'b']))
+        self.assertGdbRepr(frozenset([4, 5, 6]))
+
+    def test_exceptions(self):
+        # Test a RuntimeError
+        gdb_repr, gdb_output = self.get_gdb_repr('''
+try:
+    raise RuntimeError("I am an error")
+except RuntimeError, e:
+    print e
+''')
+        self.assertEquals(gdb_repr,
+                          "exceptions.RuntimeError('I am an error',)")
+
+
+        # Test division by zero:
+        gdb_repr, gdb_output = self.get_gdb_repr('''
+try:
+    a = 1 / 0
+except ZeroDivisionError, e:
+    print e
+''')
+        self.assertEquals(gdb_repr,
+                          "exceptions.ZeroDivisionError('integer division or modulo by zero',)")
+
+    def test_classic_class(self):
+        'Verify the pretty-printing of classic class instances'
+        gdb_repr, gdb_output = self.get_gdb_repr('''
+class Foo:
+    pass
+foo = Foo()
+foo.an_int = 42
+print foo''')
+        m = re.match(r'<Foo\(an_int=42\) at remote 0x[0-9a-f]+>', gdb_repr)
+        self.assertTrue(m,
+                        msg='Unexpected classic-class rendering %r' % gdb_repr)
+
+    def test_modern_class(self):
+        'Verify the pretty-printing of new-style class instances'
+        gdb_repr, gdb_output = self.get_gdb_repr('''
+class Foo(object):
+    pass
+foo = Foo()
+foo.an_int = 42
+print foo''')
+        m = re.match(r'<Foo\(an_int=42\) at remote 0x[0-9a-f]+>', gdb_repr)
+        self.assertTrue(m,
+                        msg='Unexpected new-style class rendering %r' % gdb_repr)
+
+    def test_subclassing_list(self):
+        'Verify the pretty-printing of an instance of a list subclass'
+        gdb_repr, gdb_output = self.get_gdb_repr('''
+class Foo(list):
+    pass
+foo = Foo()
+foo += [1, 2, 3]
+foo.an_int = 42
+print foo''')
+        m = re.match(r'<Foo\(an_int=42\) at remote 0x[0-9a-f]+>', gdb_repr)
+        self.assertTrue(m,
+                        msg='Unexpected new-style class rendering %r' % gdb_repr)
+
+    def test_subclassing_tuple(self):
+        'Verify the pretty-printing of an instance of a tuple subclass'
+        # This should exercise the negative tp_dictoffset code in the
+        # new-style class support
+        gdb_repr, gdb_output = self.get_gdb_repr('''
+class Foo(tuple):
+    pass
+foo = Foo((1, 2, 3))
+foo.an_int = 42
+print foo''')
+        m = re.match(r'<Foo\(an_int=42\) at remote 0x[0-9a-f]+>', gdb_repr)
+        self.assertTrue(m,
+                        msg='Unexpected new-style class rendering %r' % gdb_repr)
+
+    def assertSane(self, source, corruption, exp_type='unknown'):
+        '''Run Python under gdb, corrupting variables in the inferior process
+        immediately before taking a backtrace.
+
+        Verify that the variable's representation is the expected failsafe
+        representation'''
+        if corruption:
+            cmds_after_breakpoint=[corruption, 'backtrace']
+        else:
+            cmds_after_breakpoint=['backtrace']
+
+        gdb_repr, gdb_output = \
+            self.get_gdb_repr(source,
+                              cmds_after_breakpoint=cmds_after_breakpoint)
+        self.assertTrue(re.match('<%s at remote 0x[0-9a-f]+>' % exp_type,
+                                 gdb_repr),
+                        'Unexpected gdb representation: %r\n%s' % \
+                            (gdb_repr, gdb_output))
+
+    def test_NULL_ptr(self):
+        'Ensure that a NULL PyObject* is handled gracefully'
+        gdb_repr, gdb_output = (
+            self.get_gdb_repr('print 42',
+                              cmds_after_breakpoint=['set variable op=0',
+                                                         'backtrace'])
+            )
+
+        self.assertEquals(gdb_repr, '0x0')
+
+    def test_NULL_ob_type(self):
+        'Ensure that a PyObject* with NULL ob_type is handled gracefully'
+        self.assertSane('print 42',
+                        'set op->ob_type=0')
+
+    def test_corrupt_ob_type(self):
+        'Ensure that a PyObject* with a corrupt ob_type is handled gracefully'
+        self.assertSane('print 42',
+                        'set op->ob_type=0xDEADBEEF')
+
+    def test_corrupt_tp_flags(self):
+        'Ensure that a PyObject* with a type with corrupt tp_flags is handled'
+        self.assertSane('print 42',
+                        'set op->ob_type->tp_flags=0x0',
+                        exp_type='int')
+
+    def test_corrupt_tp_name(self):
+        'Ensure that a PyObject* with a type with corrupt tp_name is handled'
+        self.assertSane('print 42',
+                        'set op->ob_type->tp_name=0xDEADBEEF')
+
+    def test_NULL_instance_dict(self):
+        'Ensure that a PyInstanceObject with with a NULL in_dict is handled'
+        self.assertSane('''
+class Foo:
+    pass
+foo = Foo()
+foo.an_int = 42
+print foo''',
+                        'set ((PyInstanceObject*)op)->in_dict = 0',
+                        exp_type='Foo')
+
+    def test_builtins_help(self):
+        'Ensure that the new-style class _Helper in site.py can be handled'
+        # (this was the issue causing tracebacks in
+        #  http://bugs.python.org/issue8032#msg100537 )
+
+        gdb_repr, gdb_output = self.get_gdb_repr('print __builtins__.help', import_site=True)
+        m = re.match(r'<_Helper at remote 0x[0-9a-f]+>', gdb_repr)
+        self.assertTrue(m,
+                        msg='Unexpected rendering %r' % gdb_repr)
+
+    def test_selfreferential_list(self):
+        '''Ensure that a reference loop involving a list doesn't lead proxyval
+        into an infinite loop:'''
+        gdb_repr, gdb_output = \
+            self.get_gdb_repr("a = [3, 4, 5] ; a.append(a) ; print a")
+
+        self.assertEquals(gdb_repr, '[3, 4, 5, [...]]')
+
+        gdb_repr, gdb_output = \
+            self.get_gdb_repr("a = [3, 4, 5] ; b = [a] ; a.append(b) ; print a")
+
+        self.assertEquals(gdb_repr, '[3, 4, 5, [[...]]]')
+
+    def test_selfreferential_dict(self):
+        '''Ensure that a reference loop involving a dict doesn't lead proxyval
+        into an infinite loop:'''
+        gdb_repr, gdb_output = \
+            self.get_gdb_repr("a = {} ; b = {'bar':a} ; a['foo'] = b ; print a")
+
+        self.assertEquals(gdb_repr, "{'foo': {'bar': {...}}}")
+
+    def test_selfreferential_old_style_instance(self):
+        gdb_repr, gdb_output = \
+            self.get_gdb_repr('''
+class Foo:
+    pass
+foo = Foo()
+foo.an_attr = foo
+print foo''')
+        self.assertTrue(re.match('<Foo\(an_attr=<\.\.\.>\) at remote 0x[0-9a-f]+>',
+                                 gdb_repr),
+                        'Unexpected gdb representation: %r\n%s' % \
+                            (gdb_repr, gdb_output))
+
+    def test_selfreferential_new_style_instance(self):
+        gdb_repr, gdb_output = \
+            self.get_gdb_repr('''
+class Foo(object):
+    pass
+foo = Foo()
+foo.an_attr = foo
+print foo''')
+        self.assertTrue(re.match('<Foo\(an_attr=<\.\.\.>\) at remote 0x[0-9a-f]+>',
+                                 gdb_repr),
+                        'Unexpected gdb representation: %r\n%s' % \
+                            (gdb_repr, gdb_output))
+
+        gdb_repr, gdb_output = \
+            self.get_gdb_repr('''
+class Foo(object):
+    pass
+a = Foo()
+b = Foo()
+a.an_attr = b
+b.an_attr = a
+print a''')
+        self.assertTrue(re.match('<Foo\(an_attr=<Foo\(an_attr=<\.\.\.>\) at remote 0x[0-9a-f]+>\) at remote 0x[0-9a-f]+>',
+                                 gdb_repr),
+                        'Unexpected gdb representation: %r\n%s' % \
+                            (gdb_repr, gdb_output))
+
+    def test_truncation(self):
+        'Verify that very long output is truncated'
+        gdb_repr, gdb_output = self.get_gdb_repr('print range(1000)')
+        self.assertEquals(gdb_repr,
+                          "\n    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, "
+                          "14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, "
+                          "27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, "
+                          "40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, "
+                          "53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, "
+                          "66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, "
+                          "79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, "
+                          "92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, "
+                          "104, 105, 106, 107, 108, 109, 110, 111, 112, 113, "
+                          "114, 115, 116, 117, 118, 119, 120, 121, 122, 123, "
+                          "124, 125, 126, 127, 128, 129, 130, 131, 132, 133, "
+                          "134, 135, 136, 137, 138, 139, 140, 141, 142, 143, "
+                          "144, 145, 146, 147, 148, 149, 150, 151, 152, 153, "
+                          "154, 155, 156, 157, 158, 159, 160, 161, 162, 163, "
+                          "164, 165, 166, 167, 168, 169, 170, 171, 172, 173, "
+                          "174, 175, 176, 177, 178, 179, 180, 181, 182, 183, "
+                          "184, 185, 186, 187, 188, 189, 190, 191, 192, 193, "
+                          "194, 195, 196, 197, 198, 199, 200, 201, 202, 203, "
+                          "204, 205, 206, 207, 208, 209, 210, 211, 212, 213, "
+                          "214, 215, 216, 217, 218, 219, 220, 221, 222, 223, "
+                          "224, 225, 226...(truncated)")
+        self.assertEquals(len(gdb_repr),
+                          len('\n    ') + 1024 + len('...(truncated)'))
+
+    def test_builtin_function(self):
+        gdb_repr, gdb_output = self.get_gdb_repr('print len')
+        self.assertEquals(gdb_repr, '<built-in function len>')
+
+    def test_builtin_method(self):
+        gdb_repr, gdb_output = self.get_gdb_repr('import sys; print sys.stdout.readlines')
+        self.assertTrue(re.match('<built-in method readlines of file object at remote 0x[0-9a-f]+>',
+                                 gdb_repr),
+                        'Unexpected gdb representation: %r\n%s' % \
+                            (gdb_repr, gdb_output))
+
+    def test_frames(self):
+        gdb_output = self.get_stack_trace('''
+def foo(a, b, c):
+    pass
+
+foo(3, 4, 5)
+print foo.__code__''',
+                                          breakpoint='PyObject_Print',
+                                          cmds_after_breakpoint=['print (PyFrameObject*)(((PyCodeObject*)op)->co_zombieframe)']
+                                          )
+        for line in gdb_output.splitlines():
+            if line.startswith('$1'):
+                self.assertTrue(re.match(r'\$1 = Frame 0x[0-9a-f]+, for file <string>, line 3, in foo \(\)',
+                                         line),
+                                'Unexpected gdb representation: %r\n%s' % (line, gdb_output))
+                return
+        self.fail('Did not find expected line beginning with $1')
+
+
+
+class PyListTests(DebuggerTests):
+    def assertListing(self, expected, actual):
+        self.assertEndsWith(actual, expected)
+
+    def test_basic_command(self):
+        'Verify that the "py-list" command works'
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-list'])
+
+        self.assertListing('''
+   5
+   6    def bar(a, b, c):
+   7        baz(a, b, c)
+   8
+   9    def baz(*args):
+ >10        print(42)
+  11
+  12    foo(1, 2, 3)
+''',
+                      bt)
+
+    def test_one_abs_arg(self):
+        'Verify the "py-list" command with one absolute argument'
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-list 9'])
+
+        self.assertListing('''
+   9    def baz(*args):
+ >10        print(42)
+  11
+  12    foo(1, 2, 3)
+''',
+                      bt)
+
+    def test_two_abs_args(self):
+        'Verify the "py-list" command with two absolute arguments'
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-list 1,3'])
+
+        self.assertListing('''
+   1    # Sample script for use by test_gdb.py
+   2
+   3    def foo(a, b, c):
+''',
+                      bt)
+
+class StackNavigationTests(DebuggerTests):
+    def test_pyup_command(self):
+        'Verify that the "py-up" command works'
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-up'])
+        self.assertMultilineMatches(bt,
+                                    r'''^.*
+#[0-9]+ Frame 0x[0-9a-f]+, for file Lib/test/test_gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
+    baz\(a, b, c\)
+$''')
+
+    def test_down_at_bottom(self):
+        'Verify handling of "py-down" at the bottom of the stack'
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-down'])
+        self.assertEndsWith(bt,
+                            'Unable to find a newer python frame\n')
+
+    def test_up_at_top(self):
+        'Verify handling of "py-up" at the top of the stack'
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-up'] * 4)
+        self.assertEndsWith(bt,
+                            'Unable to find an older python frame\n')
+
+    def test_up_then_down(self):
+        'Verify "py-up" followed by "py-down"'
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-up', 'py-down'])
+        self.assertMultilineMatches(bt,
+                                    r'''^.*
+#[0-9]+ Frame 0x[0-9a-f]+, for file Lib/test/test_gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
+    baz\(a, b, c\)
+#[0-9]+ Frame 0x[0-9a-f]+, for file Lib/test/test_gdb_sample.py, line 10, in baz \(args=\(1, 2, 3\)\)
+    print\(42\)
+$''')
+
+class PyBtTests(DebuggerTests):
+    def test_basic_command(self):
+        'Verify that the "py-bt" command works'
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-bt'])
+        self.assertMultilineMatches(bt,
+                                    r'''^.*
+#[0-9]+ Frame 0x[0-9a-f]+, for file Lib/test/test_gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
+    baz\(a, b, c\)
+#[0-9]+ Frame 0x[0-9a-f]+, for file Lib/test/test_gdb_sample.py, line 4, in foo \(a=1, b=2, c=3\)
+    bar\(a, b, c\)
+#[0-9]+ Frame 0x[0-9a-f]+, for file Lib/test/test_gdb_sample.py, line 12, in <module> \(\)
+foo\(1, 2, 3\)
+''')
+
+class PyPrintTests(DebuggerTests):
+    def test_basic_command(self):
+        'Verify that the "py-print" command works'
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-print args'])
+        self.assertMultilineMatches(bt,
+                                    r".*\nlocal 'args' = \(1, 2, 3\)\n.*")
+
+    def test_print_after_up(self):
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-up', 'py-print c', 'py-print b', 'py-print a'])
+        self.assertMultilineMatches(bt,
+                                    r".*\nlocal 'c' = 3\nlocal 'b' = 2\nlocal 'a' = 1\n.*")
+
+    def test_printing_global(self):
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-print __name__'])
+        self.assertMultilineMatches(bt,
+                                    r".*\nglobal '__name__' = '__main__'\n.*")
+
+    def test_printing_builtin(self):
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-print len'])
+        self.assertMultilineMatches(bt,
+                                    r".*\nbuiltin 'len' = <built-in function len>\n.*")
+
+class PyLocalsTests(DebuggerTests):
+    def test_basic_command(self):
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-locals'])
+        self.assertMultilineMatches(bt,
+                                    r".*\nargs = \(1, 2, 3\)\n.*")
+
+    def test_locals_after_up(self):
+        bt = self.get_stack_trace(script='Lib/test/test_gdb_sample.py',
+                                  cmds_after_breakpoint=['py-up', 'py-locals'])
+        self.assertMultilineMatches(bt,
+                                    r".*\na = 1\nb = 2\nc = 3\n.*")
+
+def test_main():
+    run_unittest(PrettyPrintTests,
+                 #PyListTests,
+                 #StackNavigationTests,
+                 #PyBtTests,
+                 #PyPrintTests,
+                 #PyLocalsTests
+                 )
+
+if __name__ == "__main__":
+    test_main()
diff --git a/Lib/test/test_gdb_sample.py b/Lib/test/test_gdb_sample.py
new file mode 100644
index 0000000..a732b25
--- /dev/null
+++ b/Lib/test/test_gdb_sample.py
@@ -0,0 +1,12 @@
+# Sample script for use by test_gdb.py
+
+def foo(a, b, c):
+    bar(a, b, c)
+
+def bar(a, b, c):
+    baz(a, b, c)
+
+def baz(*args):
+    print(42)
+
+foo(1, 2, 3)
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 3a1d381..766398a 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -360,7 +360,7 @@
 
 # Default target
 all:		build_all
-build_all:	$(BUILDPYTHON) oldsharedmods sharedmods
+build_all:	$(BUILDPYTHON) oldsharedmods sharedmods gdbhooks
 
 # Compile a binary with gcc profile guided optimization.
 profile-opt:
@@ -433,6 +433,16 @@
 libpython$(VERSION).sl: $(LIBRARY_OBJS)
 	$(LDSHARED) $(LDFLAGS) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST)
 
+# Copy up the gdb python hooks into a position where they can be automatically
+# loaded by gdb during Lib/test/test_gdb.py
+#
+# Distributors are likely to want to install this somewhere else e.g. relative
+# to the stripped DWARF data for the shared library.
+gdbhooks: $(BUILDPYTHON)-gdb.py
+
+$(BUILDPYTHON)-gdb.py: Tools/gdb/libpython.py
+	$(INSTALL_SCRIPT) $< $(BUILDPYTHON)-gdb.py
+
 # This rule is here for OPENSTEP/Rhapsody/MacOSX. It builds a temporary
 # minimal framework (not including the Lib directory and such) in the current
 # directory.
@@ -1238,5 +1248,6 @@
 .PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools
 .PHONY: frameworkaltinstallunixtools recheck autoconf clean clobber distclean 
 .PHONY: smelly funny patchcheck
+.PHONY: gdbhooks
 
 # IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/Misc/ACKS b/Misc/ACKS
index 6064497..b0e89ca 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -481,6 +481,7 @@
 Nick Maclaren
 Steve Majewski
 Grzegorz Makarewicz
+David Malcolm
 Ken Manheimer
 Vladimir Marangozov
 David Marek
diff --git a/Misc/NEWS b/Misc/NEWS
index 80f1d2e..ec2da1e 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -155,6 +155,9 @@
 Build
 -----
 
+- Issue #8032: For gdb7, a python-gdb.py file is added to the build,
+  allowing to use advanced gdb features when debugging Python.
+
 - Issue #1628484: The Makefile doesn't ignore the CFLAGS environment
   variable anymore.  It also forwards the LDFLAGS settings to the linker
   when building a shared library.
diff --git a/Tools/README b/Tools/README
index 4ee8a44..6288348 100644
--- a/Tools/README
+++ b/Tools/README
@@ -20,6 +20,9 @@
 
 freeze		Create a stand-alone executable from a Python program.
 
+gdb             Python code to be run inside gdb, to make it easier to
+                debug Python itself (by David Malcolm).
+
 i18n		Tools for internationalization. pygettext.py 
 		parses Python source code and generates .pot files,
 		and msgfmt.py generates a binary message catalog 
diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py
new file mode 100644
index 0000000..26b0704
--- /dev/null
+++ b/Tools/gdb/libpython.py
@@ -0,0 +1,1392 @@
+#!/usr/bin/python
+'''
+From gdb 7 onwards, gdb's build can be configured --with-python, allowing gdb
+to be extended with Python code e.g. for library-specific data visualizations,
+such as for the C++ STL types.  Documentation on this API can be seen at:
+http://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html
+
+
+This python module deals with the case when the process being debugged (the
+"inferior process" in gdb parlance) is itself python, or more specifically,
+linked against libpython.  In this situation, almost every item of data is a
+(PyObject*), and having the debugger merely print their addresses is not very
+enlightening.
+
+This module embeds knowledge about the implementation details of libpython so
+that we can emit useful visualizations e.g. a string, a list, a dict, a frame
+giving file/line information and the state of local variables
+
+In particular, given a gdb.Value corresponding to a PyObject* in the inferior
+process, we can generate a "proxy value" within the gdb process.  For example,
+given a PyObject* in the inferior process that is in fact a PyListObject*
+holding three PyObject* that turn out to be PyStringObject* instances, we can
+generate a proxy value within the gdb process that is a list of strings:
+  ["foo", "bar", "baz"]
+
+Doing so can be expensive for complicated graphs of objects, and could take
+some time, so we also have a "write_repr" method that writes a representation
+of the data to a file-like object.  This allows us to stop the traversal by
+having the file-like object raise an exception if it gets too much data.
+
+With both "proxyval" and "write_repr" we keep track of the set of all addresses
+visited so far in the traversal, to avoid infinite recursion due to cycles in
+the graph of object references.
+
+We try to defer gdb.lookup_type() invocations for python types until as late as
+possible: for a dynamically linked python binary, when the process starts in
+the debugger, the libpython.so hasn't been dynamically loaded yet, so none of
+the type names are known to the debugger
+
+The module also extends gdb with some python-specific commands.
+'''
+from __future__ import with_statement
+import gdb
+
+# Look up the gdb.Type for some standard types:
+_type_char_ptr = gdb.lookup_type('char').pointer() # char*
+_type_unsigned_char_ptr = gdb.lookup_type('unsigned char').pointer() # unsigned char*
+_type_void_ptr = gdb.lookup_type('void').pointer() # void*
+_type_size_t = gdb.lookup_type('size_t')
+
+SIZEOF_VOID_P = _type_void_ptr.sizeof
+
+
+Py_TPFLAGS_HEAPTYPE = (1L << 9)
+
+Py_TPFLAGS_INT_SUBCLASS      = (1L << 23)
+Py_TPFLAGS_LONG_SUBCLASS     = (1L << 24)
+Py_TPFLAGS_LIST_SUBCLASS     = (1L << 25)
+Py_TPFLAGS_TUPLE_SUBCLASS    = (1L << 26)
+Py_TPFLAGS_STRING_SUBCLASS   = (1L << 27)
+Py_TPFLAGS_UNICODE_SUBCLASS  = (1L << 28)
+Py_TPFLAGS_DICT_SUBCLASS     = (1L << 29)
+Py_TPFLAGS_BASE_EXC_SUBCLASS = (1L << 30)
+Py_TPFLAGS_TYPE_SUBCLASS     = (1L << 31)
+
+
+MAX_OUTPUT_LEN=1024
+
+class NullPyObjectPtr(RuntimeError):
+    pass
+
+
+def safety_limit(val):
+    # Given a integer value from the process being debugged, limit it to some
+    # safety threshold so that arbitrary breakage within said process doesn't
+    # break the gdb process too much (e.g. sizes of iterations, sizes of lists)
+    return min(val, 1000)
+
+
+def safe_range(val):
+    # As per range, but don't trust the value too much: cap it to a safety
+    # threshold in case the data was corrupted
+    return xrange(safety_limit(val))
+
+
+class StringTruncated(RuntimeError):
+    pass
+
+class TruncatedStringIO(object):
+    '''Similar to cStringIO, but can truncate the output by raising a
+    StringTruncated exception'''
+    def __init__(self, maxlen=None):
+        self._val = ''
+        self.maxlen = maxlen
+
+    def write(self, data):
+        if self.maxlen:
+            if len(data) + len(self._val) > self.maxlen:
+                # Truncation:
+                self._val += data[0:self.maxlen - len(self._val)]
+                raise StringTruncated()
+
+        self._val += data
+
+    def getvalue(self):
+        return self._val
+
+class PyObjectPtr(object):
+    """
+    Class wrapping a gdb.Value that's a either a (PyObject*) within the
+    inferior process, or some subclass pointer e.g. (PyStringObject*)
+
+    There will be a subclass for every refined PyObject type that we care
+    about.
+
+    Note that at every stage the underlying pointer could be NULL, point
+    to corrupt data, etc; this is the debugger, after all.
+    """
+    _typename = 'PyObject'
+
+    def __init__(self, gdbval, cast_to=None):
+        if cast_to:
+            self._gdbval = gdbval.cast(cast_to)
+        else:
+            self._gdbval = gdbval
+
+    def field(self, name):
+        '''
+        Get the gdb.Value for the given field within the PyObject, coping with
+        some python 2 versus python 3 differences.
+
+        Various libpython types are defined using the "PyObject_HEAD" and
+        "PyObject_VAR_HEAD" macros.
+
+        In Python 2, this these are defined so that "ob_type" and (for a var
+        object) "ob_size" are fields of the type in question.
+
+        In Python 3, this is defined as an embedded PyVarObject type thus:
+           PyVarObject ob_base;
+        so that the "ob_size" field is located insize the "ob_base" field, and
+        the "ob_type" is most easily accessed by casting back to a (PyObject*).
+        '''
+        if self.is_null():
+            raise NullPyObjectPtr(self)
+
+        if name == 'ob_type':
+            pyo_ptr = self._gdbval.cast(PyObjectPtr.get_gdb_type())
+            return pyo_ptr.dereference()[name]
+
+        if name == 'ob_size':
+            try:
+            # Python 2:
+                return self._gdbval.dereference()[name]
+            except RuntimeError:
+                # Python 3:
+                return self._gdbval.dereference()['ob_base'][name]
+
+        # General case: look it up inside the object:
+        return self._gdbval.dereference()[name]
+
+    def pyop_field(self, name):
+        '''
+        Get a PyObjectPtr for the given PyObject* field within this PyObject,
+        coping with some python 2 versus python 3 differences.
+        '''
+        return PyObjectPtr.from_pyobject_ptr(self.field(name))
+
+    def write_field_repr(self, name, out, visited):
+        '''
+        Extract the PyObject* field named "name", and write its representation
+        to file-like object "out"
+        '''
+        field_obj = self.pyop_field(name)
+        field_obj.write_repr(out, visited)
+
+    def get_truncated_repr(self, maxlen):
+        '''
+        Get a repr-like string for the data, but truncate it at "maxlen" bytes
+        (ending the object graph traversal as soon as you do)
+        '''
+        out = TruncatedStringIO(maxlen)
+        try:
+            self.write_repr(out, set())
+        except StringTruncated:
+            # Truncation occurred:
+            return out.getvalue() + '...(truncated)'
+
+        # No truncation occurred:
+        return out.getvalue()
+
+    def type(self):
+        return PyTypeObjectPtr(self.field('ob_type'))
+
+    def is_null(self):
+        return 0 == long(self._gdbval)
+
+    def is_optimized_out(self):
+        '''
+        Is the value of the underlying PyObject* visible to the debugger?
+
+        This can vary with the precise version of the compiler used to build
+        Python, and the precise version of gdb.
+
+        See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=556975 with
+        PyEval_EvalFrameEx's "f"
+        '''
+        return self._gdbval.is_optimized_out
+
+    def safe_tp_name(self):
+        try:
+            return self.type().field('tp_name').string()
+        except NullPyObjectPtr:
+            # NULL tp_name?
+            return 'unknown'
+        except RuntimeError:
+            # Can't even read the object at all?
+            return 'unknown'
+
+    def proxyval(self, visited):
+        '''
+        Scrape a value from the inferior process, and try to represent it
+        within the gdb process, whilst (hopefully) avoiding crashes when
+        the remote data is corrupt.
+
+        Derived classes will override this.
+
+        For example, a PyIntObject* with ob_ival 42 in the inferior process
+        should result in an int(42) in this process.
+
+        visited: a set of all gdb.Value pyobject pointers already visited
+        whilst generating this value (to guard against infinite recursion when
+        visiting object graphs with loops).  Analogous to Py_ReprEnter and
+        Py_ReprLeave
+        '''
+
+        class FakeRepr(object):
+            """
+            Class representing a non-descript PyObject* value in the inferior
+            process for when we don't have a custom scraper, intended to have
+            a sane repr().
+            """
+
+            def __init__(self, tp_name, address):
+                self.tp_name = tp_name
+                self.address = address
+
+            def __repr__(self):
+                # For the NULL pointer, we have no way of knowing a type, so
+                # special-case it as per
+                # http://bugs.python.org/issue8032#msg100882
+                if self.address == 0:
+                    return '0x0'
+                return '<%s at remote 0x%x>' % (self.tp_name, self.address)
+
+        return FakeRepr(self.safe_tp_name(),
+                        long(self._gdbval))
+
+    def write_repr(self, out, visited):
+        '''
+        Write a string representation of the value scraped from the inferior
+        process to "out", a file-like object.
+        '''
+        # Default implementation: generate a proxy value and write its repr
+        # However, this could involve a lot of work for complicated objects,
+        # so for derived classes we specialize this
+        return out.write(repr(self.proxyval(visited)))
+
+    @classmethod
+    def subclass_from_type(cls, t):
+        '''
+        Given a PyTypeObjectPtr instance wrapping a gdb.Value that's a
+        (PyTypeObject*), determine the corresponding subclass of PyObjectPtr
+        to use
+
+        Ideally, we would look up the symbols for the global types, but that
+        isn't working yet:
+          (gdb) python print gdb.lookup_symbol('PyList_Type')[0].value
+          Traceback (most recent call last):
+            File "<string>", line 1, in <module>
+          NotImplementedError: Symbol type not yet supported in Python scripts.
+          Error while executing Python code.
+
+        For now, we use tp_flags, after doing some string comparisons on the
+        tp_name for some special-cases that don't seem to be visible through
+        flags
+        '''
+        try:
+            tp_name = t.field('tp_name').string()
+            tp_flags = int(t.field('tp_flags'))
+        except RuntimeError:
+            # Handle any kind of error e.g. NULL ptrs by simply using the base
+            # class
+            return cls
+
+        #print 'tp_flags = 0x%08x' % tp_flags
+        #print 'tp_name = %r' % tp_name
+
+        name_map = {'bool': PyBoolObjectPtr,
+                    'classobj': PyClassObjectPtr,
+                    'instance': PyInstanceObjectPtr,
+                    'NoneType': PyNoneStructPtr,
+                    'frame': PyFrameObjectPtr,
+                    'set' : PySetObjectPtr,
+                    'frozenset' : PySetObjectPtr,
+                    'builtin_function_or_method' : PyCFunctionObjectPtr,
+                    }
+        if tp_name in name_map:
+            return name_map[tp_name]
+
+        if tp_flags & Py_TPFLAGS_HEAPTYPE:
+            return HeapTypeObjectPtr
+
+        if tp_flags & Py_TPFLAGS_INT_SUBCLASS:
+            return PyIntObjectPtr
+        if tp_flags & Py_TPFLAGS_LONG_SUBCLASS:
+            return PyLongObjectPtr
+        if tp_flags & Py_TPFLAGS_LIST_SUBCLASS:
+            return PyListObjectPtr
+        if tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS:
+            return PyTupleObjectPtr
+        if tp_flags & Py_TPFLAGS_STRING_SUBCLASS:
+            return PyStringObjectPtr
+        if tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS:
+            return PyUnicodeObjectPtr
+        if tp_flags & Py_TPFLAGS_DICT_SUBCLASS:
+            return PyDictObjectPtr
+        if tp_flags & Py_TPFLAGS_BASE_EXC_SUBCLASS:
+            return PyBaseExceptionObjectPtr
+        #if tp_flags & Py_TPFLAGS_TYPE_SUBCLASS:
+        #    return PyTypeObjectPtr
+
+        # Use the base class:
+        return cls
+
+    @classmethod
+    def from_pyobject_ptr(cls, gdbval):
+        '''
+        Try to locate the appropriate derived class dynamically, and cast
+        the pointer accordingly.
+        '''
+        try:
+            p = PyObjectPtr(gdbval)
+            cls = cls.subclass_from_type(p.type())
+            return cls(gdbval, cast_to=cls.get_gdb_type())
+        except RuntimeError:
+            # Handle any kind of error e.g. NULL ptrs by simply using the base
+            # class
+            pass
+        return cls(gdbval)
+
+    @classmethod
+    def get_gdb_type(cls):
+        return gdb.lookup_type(cls._typename).pointer()
+
+    def as_address(self):
+        return long(self._gdbval)
+
+
+class ProxyAlreadyVisited(object):
+    '''
+    Placeholder proxy to use when protecting against infinite recursion due to
+    loops in the object graph.
+
+    Analogous to the values emitted by the users of Py_ReprEnter and Py_ReprLeave
+    '''
+    def __init__(self, rep):
+        self._rep = rep
+
+    def __repr__(self):
+        return self._rep
+
+
+def _write_instance_repr(out, visited, name, pyop_attrdict, address):
+    '''Shared code for use by old-style and new-style classes:
+    write a representation to file-like object "out"'''
+    out.write('<')
+    out.write(name)
+
+    # Write dictionary of instance attributes:
+    if isinstance(pyop_attrdict, PyDictObjectPtr):
+        out.write('(')
+        first = True
+        for pyop_arg, pyop_val in pyop_attrdict.iteritems():
+            if not first:
+                out.write(', ')
+            first = False
+            out.write(pyop_arg.proxyval(visited))
+            out.write('=')
+            pyop_val.write_repr(out, visited)
+        out.write(')')
+    out.write(' at remote 0x%x>' % address)
+
+
+class InstanceProxy(object):
+
+    def __init__(self, cl_name, attrdict, address):
+        self.cl_name = cl_name
+        self.attrdict = attrdict
+        self.address = address
+
+    def __repr__(self):
+        if isinstance(self.attrdict, dict):
+            kwargs = ', '.join(["%s=%r" % (arg, val)
+                                for arg, val in self.attrdict.iteritems()])
+            return '<%s(%s) at remote 0x%x>' % (self.cl_name,
+                                                kwargs, self.address)
+        else:
+            return '<%s at remote 0x%x>' % (self.cl_name,
+                                            self.address)
+
+def _PyObject_VAR_SIZE(typeobj, nitems):
+    return ( ( typeobj.field('tp_basicsize') +
+               nitems * typeobj.field('tp_itemsize') +
+               (SIZEOF_VOID_P - 1)
+             ) & ~(SIZEOF_VOID_P - 1)
+           ).cast(_type_size_t)
+
+class HeapTypeObjectPtr(PyObjectPtr):
+    _typename = 'PyObject'
+
+    def get_attr_dict(self):
+        '''
+        Get the PyDictObject ptr representing the attribute dictionary
+        (or None if there's a problem)
+        '''
+        try:
+            typeobj = self.type()
+            dictoffset = int_from_int(typeobj.field('tp_dictoffset'))
+            if dictoffset != 0:
+                if dictoffset < 0:
+                    type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer()
+                    tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size'])
+                    if tsize < 0:
+                        tsize = -tsize
+                    size = _PyObject_VAR_SIZE(typeobj, tsize)
+                    dictoffset += size
+                    assert dictoffset > 0
+                    assert dictoffset % SIZEOF_VOID_P == 0
+
+                dictptr = self._gdbval.cast(_type_char_ptr) + dictoffset
+                PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer()
+                dictptr = dictptr.cast(PyObjectPtrPtr)
+                return PyObjectPtr.from_pyobject_ptr(dictptr.dereference())
+        except RuntimeError:
+            # Corrupt data somewhere; fail safe
+            pass
+
+        # Not found, or some kind of error:
+        return None
+
+    def proxyval(self, visited):
+        '''
+        Support for new-style classes.
+
+        Currently we just locate the dictionary using a transliteration to
+        python of _PyObject_GetDictPtr, ignoring descriptors
+        '''
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            return ProxyAlreadyVisited('<...>')
+        visited.add(self.as_address())
+
+        pyop_attr_dict = self.get_attr_dict()
+        if pyop_attr_dict:
+            attr_dict = pyop_attr_dict.proxyval(visited)
+        else:
+            attr_dict = {}
+        tp_name = self.safe_tp_name()
+
+        # New-style class:
+        return InstanceProxy(tp_name, attr_dict, long(self._gdbval))
+
+    def write_repr(self, out, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            out.write('<...>')
+            return
+        visited.add(self.as_address())
+
+        pyop_attrdict = self.get_attr_dict()
+        _write_instance_repr(out, visited,
+                             self.safe_tp_name(), pyop_attrdict, self.as_address())
+
+class ProxyException(Exception):
+    def __init__(self, tp_name, args):
+        self.tp_name = tp_name
+        self.args = args
+
+    def __repr__(self):
+        return '%s%r' % (self.tp_name, self.args)
+
+class PyBaseExceptionObjectPtr(PyObjectPtr):
+    """
+    Class wrapping a gdb.Value that's a PyBaseExceptionObject* i.e. an exception
+    within the process being debugged.
+    """
+    _typename = 'PyBaseExceptionObject'
+
+    def proxyval(self, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            return ProxyAlreadyVisited('(...)')
+        visited.add(self.as_address())
+        arg_proxy = self.pyop_field('args').proxyval(visited)
+        return ProxyException(self.safe_tp_name(),
+                              arg_proxy)
+
+    def write_repr(self, out, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            out.write('(...)')
+            return
+        visited.add(self.as_address())
+
+        out.write(self.safe_tp_name())
+        self.write_field_repr('args', out, visited)
+
+class PyBoolObjectPtr(PyObjectPtr):
+    """
+    Class wrapping a gdb.Value that's a PyBoolObject* i.e. one of the two
+    <bool> instances (Py_True/Py_False) within the process being debugged.
+    """
+    _typename = 'PyBoolObject'
+
+    def proxyval(self, visited):
+        if int_from_int(self.field('ob_ival')):
+            return True
+        else:
+            return False
+
+
+class PyClassObjectPtr(PyObjectPtr):
+    """
+    Class wrapping a gdb.Value that's a PyClassObject* i.e. a <classobj>
+    instance within the process being debugged.
+    """
+    _typename = 'PyClassObject'
+
+
+class BuiltInFunctionProxy(object):
+    def __init__(self, ml_name):
+        self.ml_name = ml_name
+
+    def __repr__(self):
+        return "<built-in function %s>" % self.ml_name
+
+class BuiltInMethodProxy(object):
+    def __init__(self, ml_name, pyop_m_self):
+        self.ml_name = ml_name
+        self.pyop_m_self = pyop_m_self
+
+    def __repr__(self):
+        return ('<built-in method %s of %s object at remote 0x%x>'
+                % (self.ml_name,
+                   self.pyop_m_self.safe_tp_name(),
+                   self.pyop_m_self.as_address())
+                )
+
+class PyCFunctionObjectPtr(PyObjectPtr):
+    """
+    Class wrapping a gdb.Value that's a PyCFunctionObject*
+    (see Include/methodobject.h and Objects/methodobject.c)
+    """
+    _typename = 'PyCFunctionObject'
+
+    def proxyval(self, visited):
+        m_ml = self.field('m_ml') # m_ml is a (PyMethodDef*)
+        ml_name = m_ml['ml_name'].string()
+
+        pyop_m_self = self.pyop_field('m_self')
+        if pyop_m_self.is_null():
+            return BuiltInFunctionProxy(ml_name)
+        else:
+            return BuiltInMethodProxy(ml_name, pyop_m_self)
+
+
+class PyCodeObjectPtr(PyObjectPtr):
+    """
+    Class wrapping a gdb.Value that's a PyCodeObject* i.e. a <code> instance
+    within the process being debugged.
+    """
+    _typename = 'PyCodeObject'
+
+    def addr2line(self, addrq):
+        '''
+        Get the line number for a given bytecode offset
+
+        Analogous to PyCode_Addr2Line; translated from pseudocode in
+        Objects/lnotab_notes.txt
+        '''
+        co_lnotab = self.pyop_field('co_lnotab').proxyval(set())
+
+        # Initialize lineno to co_firstlineno as per PyCode_Addr2Line
+        # not 0, as lnotab_notes.txt has it:
+        lineno = int_from_int(self.field('co_firstlineno'))
+
+        addr = 0
+        for addr_incr, line_incr in zip(co_lnotab[::2], co_lnotab[1::2]):
+            addr += ord(addr_incr)
+            if addr > addrq:
+                return lineno
+            lineno += ord(line_incr)
+        return lineno
+
+
+class PyDictObjectPtr(PyObjectPtr):
+    """
+    Class wrapping a gdb.Value that's a PyDictObject* i.e. a dict instance
+    within the process being debugged.
+    """
+    _typename = 'PyDictObject'
+
+    def iteritems(self):
+        '''
+        Yields a sequence of (PyObjectPtr key, PyObjectPtr value) pairs,
+        analagous to dict.iteritems()
+        '''
+        for i in safe_range(self.field('ma_mask') + 1):
+            ep = self.field('ma_table') + i
+            pyop_value = PyObjectPtr.from_pyobject_ptr(ep['me_value'])
+            if not pyop_value.is_null():
+                pyop_key = PyObjectPtr.from_pyobject_ptr(ep['me_key'])
+                yield (pyop_key, pyop_value)
+
+    def proxyval(self, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            return ProxyAlreadyVisited('{...}')
+        visited.add(self.as_address())
+
+        result = {}
+        for pyop_key, pyop_value in self.iteritems():
+            proxy_key = pyop_key.proxyval(visited)
+            proxy_value = pyop_value.proxyval(visited)
+            result[proxy_key] = proxy_value
+        return result
+
+    def write_repr(self, out, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            out.write('{...}')
+            return
+        visited.add(self.as_address())
+
+        out.write('{')
+        first = True
+        for pyop_key, pyop_value in self.iteritems():
+            if not first:
+                out.write(', ')
+            first = False
+            pyop_key.write_repr(out, visited)
+            out.write(': ')
+            pyop_value.write_repr(out, visited)
+        out.write('}')
+
+class PyInstanceObjectPtr(PyObjectPtr):
+    _typename = 'PyInstanceObject'
+
+    def proxyval(self, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            return ProxyAlreadyVisited('<...>')
+        visited.add(self.as_address())
+
+        # Get name of class:
+        in_class = self.pyop_field('in_class')
+        cl_name = in_class.pyop_field('cl_name').proxyval(visited)
+
+        # Get dictionary of instance attributes:
+        in_dict = self.pyop_field('in_dict').proxyval(visited)
+
+        # Old-style class:
+        return InstanceProxy(cl_name, in_dict, long(self._gdbval))
+
+    def write_repr(self, out, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            out.write('<...>')
+            return
+        visited.add(self.as_address())
+
+        # Old-style class:
+
+        # Get name of class:
+        in_class = self.pyop_field('in_class')
+        cl_name = in_class.pyop_field('cl_name').proxyval(visited)
+
+        # Get dictionary of instance attributes:
+        pyop_in_dict = self.pyop_field('in_dict')
+
+        _write_instance_repr(out, visited,
+                             cl_name, pyop_in_dict, self.as_address())
+
+class PyIntObjectPtr(PyObjectPtr):
+    _typename = 'PyIntObject'
+
+    def proxyval(self, visited):
+        result = int_from_int(self.field('ob_ival'))
+        return result
+
+class PyListObjectPtr(PyObjectPtr):
+    _typename = 'PyListObject'
+
+    def __getitem__(self, i):
+        # Get the gdb.Value for the (PyObject*) with the given index:
+        field_ob_item = self.field('ob_item')
+        return field_ob_item[i]
+
+    def proxyval(self, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            return ProxyAlreadyVisited('[...]')
+        visited.add(self.as_address())
+
+        result = [PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited)
+                  for i in safe_range(int_from_int(self.field('ob_size')))]
+        return result
+
+    def write_repr(self, out, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            out.write('[...]')
+            return
+        visited.add(self.as_address())
+
+        out.write('[')
+        for i in safe_range(int_from_int(self.field('ob_size'))):
+            if i > 0:
+                out.write(', ')
+            element = PyObjectPtr.from_pyobject_ptr(self[i])
+            element.write_repr(out, visited)
+        out.write(']')
+
+class PyLongObjectPtr(PyObjectPtr):
+    _typename = 'PyLongObject'
+
+    def proxyval(self, visited):
+        '''
+        Python's Include/longobjrep.h has this declaration:
+           struct _longobject {
+               PyObject_VAR_HEAD
+               digit ob_digit[1];
+           };
+
+        with this description:
+            The absolute value of a number is equal to
+                 SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
+            Negative numbers are represented with ob_size < 0;
+            zero is represented by ob_size == 0.
+
+        where SHIFT can be either:
+            #define PyLong_SHIFT        30
+            #define PyLong_SHIFT        15
+        '''
+        ob_size = long(self.field('ob_size'))
+        if ob_size == 0:
+            return 0L
+
+        ob_digit = self.field('ob_digit')
+
+        if gdb.lookup_type('digit').sizeof == 2:
+            SHIFT = 15L
+        else:
+            SHIFT = 30L
+
+        digits = [long(ob_digit[i]) * 2**(SHIFT*i)
+                  for i in safe_range(abs(ob_size))]
+        result = sum(digits)
+        if ob_size < 0:
+            result = -result
+        return result
+
+
+class PyNoneStructPtr(PyObjectPtr):
+    """
+    Class wrapping a gdb.Value that's a PyObject* pointing to the
+    singleton (we hope) _Py_NoneStruct with ob_type PyNone_Type
+    """
+    _typename = 'PyObject'
+
+    def proxyval(self, visited):
+        return None
+
+
+class PyFrameObjectPtr(PyObjectPtr):
+    _typename = 'PyFrameObject'
+
+    def __init__(self, gdbval, cast_to):
+        PyObjectPtr.__init__(self, gdbval, cast_to)
+
+        if not self.is_optimized_out():
+            self.co = PyCodeObjectPtr.from_pyobject_ptr(self.field('f_code'))
+            self.co_name = self.co.pyop_field('co_name')
+            self.co_filename = self.co.pyop_field('co_filename')
+
+            self.f_lineno = int_from_int(self.field('f_lineno'))
+            self.f_lasti = int_from_int(self.field('f_lasti'))
+            self.co_nlocals = int_from_int(self.co.field('co_nlocals'))
+            self.co_varnames = PyTupleObjectPtr.from_pyobject_ptr(self.co.field('co_varnames'))
+
+    def iter_locals(self):
+        '''
+        Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
+        the local variables of this frame
+        '''
+        if self.is_optimized_out():
+            return
+
+        f_localsplus = self.field('f_localsplus')
+        for i in safe_range(self.co_nlocals):
+            pyop_value = PyObjectPtr.from_pyobject_ptr(f_localsplus[i])
+            if not pyop_value.is_null():
+                pyop_name = PyObjectPtr.from_pyobject_ptr(self.co_varnames[i])
+                yield (pyop_name, pyop_value)
+
+    def iter_globals(self):
+        '''
+        Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
+        the global variables of this frame
+        '''
+        if self.is_optimized_out():
+            return
+
+        pyop_globals = self.pyop_field('f_globals')
+        return pyop_globals.iteritems()
+
+    def iter_builtins(self):
+        '''
+        Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
+        the builtin variables
+        '''
+        if self.is_optimized_out():
+            return
+
+        pyop_builtins = self.pyop_field('f_builtins')
+        return pyop_builtins.iteritems()
+
+    def get_var_by_name(self, name):
+        '''
+        Look for the named local variable, returning a (PyObjectPtr, scope) pair
+        where scope is a string 'local', 'global', 'builtin'
+
+        If not found, return (None, None)
+        '''
+        for pyop_name, pyop_value in self.iter_locals():
+            if name == pyop_name.proxyval(set()):
+                return pyop_value, 'local'
+        for pyop_name, pyop_value in self.iter_globals():
+            if name == pyop_name.proxyval(set()):
+                return pyop_value, 'global'
+        for pyop_name, pyop_value in self.iter_builtins():
+            if name == pyop_name.proxyval(set()):
+                return pyop_value, 'builtin'
+        return None, None
+
+    def filename(self):
+        '''Get the path of the current Python source file, as a string'''
+        if self.is_optimized_out():
+            return '(frame information optimized out)'
+        return self.co_filename.proxyval(set())
+
+    def current_line_num(self):
+        '''Get current line number as an integer (1-based)
+
+        Translated from PyFrame_GetLineNumber and PyCode_Addr2Line
+
+        See Objects/lnotab_notes.txt
+        '''
+        if self.is_optimized_out():
+            return None
+        f_trace = self.field('f_trace')
+        if long(f_trace) != 0:
+            # we have a non-NULL f_trace:
+            return self.f_lineno
+        else:
+            #try:
+            return self.co.addr2line(self.f_lasti)
+            #except ValueError:
+            #    return self.f_lineno
+
+    def current_line(self):
+        '''Get the text of the current source line as a string, with a trailing
+        newline character'''
+        if self.is_optimized_out():
+            return '(frame information optimized out)'
+        with open(self.filename(), 'r') as f:
+            all_lines = f.readlines()
+            # Convert from 1-based current_line_num to 0-based list offset:
+            return all_lines[self.current_line_num()-1]
+
+    def write_repr(self, out, visited):
+        if self.is_optimized_out():
+            out.write('(frame information optimized out)')
+            return
+        out.write('Frame 0x%x, for file %s, line %i, in %s ('
+                  % (self.as_address(),
+                     self.co_filename,
+                     self.current_line_num(),
+                     self.co_name))
+        first = True
+        for pyop_name, pyop_value in self.iter_locals():
+            if not first:
+                out.write(', ')
+            first = False
+
+            out.write(pyop_name.proxyval(visited))
+            out.write('=')
+            pyop_value.write_repr(out, visited)
+
+        out.write(')')
+
+class PySetObjectPtr(PyObjectPtr):
+    _typename = 'PySetObject'
+
+    def proxyval(self, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            return ProxyAlreadyVisited('%s(...)' % self.safe_tp_name())
+        visited.add(self.as_address())
+
+        members = []
+        table = self.field('table')
+        for i in safe_range(self.field('mask')+1):
+            setentry = table[i]
+            key = setentry['key']
+            if key != 0:
+                key_proxy = PyObjectPtr.from_pyobject_ptr(key).proxyval(visited)
+                if key_proxy != '<dummy key>':
+                    members.append(key_proxy)
+        if self.safe_tp_name() == 'frozenset':
+            return frozenset(members)
+        else:
+            return set(members)
+
+    def write_repr(self, out, visited):
+        out.write(self.safe_tp_name())
+
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            out.write('(...)')
+            return
+        visited.add(self.as_address())
+
+        out.write('([')
+        first = True
+        table = self.field('table')
+        for i in safe_range(self.field('mask')+1):
+            setentry = table[i]
+            key = setentry['key']
+            if key != 0:
+                pyop_key = PyObjectPtr.from_pyobject_ptr(key)
+                key_proxy = pyop_key.proxyval(visited) # FIXME!
+                if key_proxy != '<dummy key>':
+                    if not first:
+                        out.write(', ')
+                    first = False
+                    pyop_key.write_repr(out, visited)
+        out.write('])')
+
+
+class PyStringObjectPtr(PyObjectPtr):
+    _typename = 'PyStringObject'
+
+    def __str__(self):
+        field_ob_size = self.field('ob_size')
+        field_ob_sval = self.field('ob_sval')
+        char_ptr = field_ob_sval.address.cast(_type_unsigned_char_ptr)
+        return ''.join([chr(char_ptr[i]) for i in safe_range(field_ob_size)])
+
+    def proxyval(self, visited):
+        return str(self)
+
+class PyTupleObjectPtr(PyObjectPtr):
+    _typename = 'PyTupleObject'
+
+    def __getitem__(self, i):
+        # Get the gdb.Value for the (PyObject*) with the given index:
+        field_ob_item = self.field('ob_item')
+        return field_ob_item[i]
+
+    def proxyval(self, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            return ProxyAlreadyVisited('(...)')
+        visited.add(self.as_address())
+
+        result = tuple([PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited)
+                        for i in safe_range(int_from_int(self.field('ob_size')))])
+        return result
+
+    def write_repr(self, out, visited):
+        # Guard against infinite loops:
+        if self.as_address() in visited:
+            out.write('(...)')
+            return
+        visited.add(self.as_address())
+
+        out.write('(')
+        for i in safe_range(int_from_int(self.field('ob_size'))):
+            if i > 0:
+                out.write(', ')
+            element = PyObjectPtr.from_pyobject_ptr(self[i])
+            element.write_repr(out, visited)
+        if self.field('ob_size') == 1:
+            out.write(',)')
+        else:
+            out.write(')')
+
+class PyTypeObjectPtr(PyObjectPtr):
+    _typename = 'PyTypeObject'
+
+
+class PyUnicodeObjectPtr(PyObjectPtr):
+    _typename = 'PyUnicodeObject'
+
+    def proxyval(self, visited):
+        # From unicodeobject.h:
+        #     Py_ssize_t length;  /* Length of raw Unicode data in buffer */
+        #     Py_UNICODE *str;    /* Raw Unicode buffer */
+        field_length = long(self.field('length'))
+        field_str = self.field('str')
+
+        # Gather a list of ints from the Py_UNICODE array; these are either
+        # UCS-2 or UCS-4 code points:
+        Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)]
+
+        # Convert the int code points to unicode characters, and generate a
+        # local unicode instance:
+        result = u''.join([unichr(ucs) for ucs in Py_UNICODEs])
+        return result
+
+
+def int_from_int(gdbval):
+    return int(str(gdbval))
+
+
+def stringify(val):
+    # TODO: repr() puts everything on one line; pformat can be nicer, but
+    # can lead to v.long results; this function isolates the choice
+    if True:
+        return repr(val)
+    else:
+        from pprint import pformat
+        return pformat(val)
+
+
+class PyObjectPtrPrinter:
+    "Prints a (PyObject*)"
+
+    def __init__ (self, gdbval):
+        self.gdbval = gdbval
+
+    def to_string (self):
+        pyop = PyObjectPtr.from_pyobject_ptr(self.gdbval)
+        if True:
+            return pyop.get_truncated_repr(MAX_OUTPUT_LEN)
+        else:
+            # Generate full proxy value then stringify it.
+            # Doing so could be expensive
+            proxyval = pyop.proxyval(set())
+            return stringify(proxyval)
+
+def pretty_printer_lookup(gdbval):
+    type = gdbval.type.unqualified()
+    if type.code == gdb.TYPE_CODE_PTR:
+        type = type.target().unqualified()
+        t = str(type)
+        if t in ("PyObject", "PyFrameObject"):
+            return PyObjectPtrPrinter(gdbval)
+
+"""
+During development, I've been manually invoking the code in this way:
+(gdb) python
+
+import sys
+sys.path.append('/home/david/coding/python-gdb')
+import libpython
+end
+
+then reloading it after each edit like this:
+(gdb) python reload(libpython)
+
+The following code should ensure that the prettyprinter is registered
+if the code is autoloaded by gdb when visiting libpython.so, provided
+that this python file is installed to the same path as the library (or its
+.debug file) plus a "-gdb.py" suffix, e.g:
+  /usr/lib/libpython2.6.so.1.0-gdb.py
+  /usr/lib/debug/usr/lib/libpython2.6.so.1.0.debug-gdb.py
+"""
+def register (obj):
+    if obj == None:
+        obj = gdb
+
+    # Wire up the pretty-printer
+    obj.pretty_printers.append(pretty_printer_lookup)
+
+register (gdb.current_objfile ())
+
+
+class Frame(object):
+    '''
+    Wrapper for gdb.Frame, adding various methods
+    '''
+    def __init__(self, gdbframe):
+        self._gdbframe = gdbframe
+
+    def older(self):
+        older = self._gdbframe.older()
+        if older:
+            return Frame(older)
+        else:
+            return None
+
+    def newer(self):
+        newer = self._gdbframe.newer()
+        if newer:
+            return Frame(newer)
+        else:
+            return None
+
+    def select(self):
+        self._gdbframe.select()
+
+    def get_index(self):
+        '''Calculate index of frame, starting at 0 for the newest frame within
+        this thread'''
+        index = 0
+        # Go down until you reach the newest frame:
+        iter_frame = self
+        while iter_frame.newer():
+            index += 1
+            iter_frame = iter_frame.newer()
+        return index
+
+    def is_evalframeex(self):
+        if self._gdbframe.function():
+            if self._gdbframe.function().name == 'PyEval_EvalFrameEx':
+                '''
+                I believe we also need to filter on the inline
+                struct frame_id.inline_depth, only regarding frames with
+                an inline depth of 0 as actually being this function
+
+                So we reject those with type gdb.INLINE_FRAME
+                '''
+                if self._gdbframe.type() == gdb.NORMAL_FRAME:
+                    # We have a PyEval_EvalFrameEx frame:
+                    return True
+
+        return False
+
+    def get_pyop(self):
+        try:
+            f = self._gdbframe.read_var('f')
+            return PyFrameObjectPtr.from_pyobject_ptr(f)
+        except ValueError:
+            return None
+
+    @classmethod
+    def get_selected_frame(cls):
+        _gdbframe = gdb.selected_frame()
+        if _gdbframe:
+            return Frame(_gdbframe)
+        return None
+
+    @classmethod
+    def get_selected_python_frame(cls):
+        '''Try to obtain the Frame for the python code in the selected frame,
+        or None'''
+        frame = cls.get_selected_frame()
+
+        while frame:
+            if frame.is_evalframeex():
+                return frame
+            frame = frame.older()
+
+        # Not found:
+        return None
+
+    def print_summary(self):
+        if self.is_evalframeex():
+            pyop = self.get_pyop()
+            if pyop:
+                sys.stdout.write('#%i %s\n' % (self.get_index(), pyop.get_truncated_repr(MAX_OUTPUT_LEN)))
+                sys.stdout.write(pyop.current_line())
+            else:
+                sys.stdout.write('#%i (unable to read python frame information)\n' % self.get_index())
+        else:
+            sys.stdout.write('#%i\n' % self.get_index())
+
+class PyList(gdb.Command):
+    '''List the current Python source code, if any
+
+    Use
+       py-list START
+    to list at a different line number within the python source.
+
+    Use
+       py-list START, END
+    to list a specific range of lines within the python source.
+    '''
+
+    def __init__(self):
+        gdb.Command.__init__ (self,
+                              "py-list",
+                              gdb.COMMAND_FILES,
+                              gdb.COMPLETE_NONE)
+
+
+    def invoke(self, args, from_tty):
+        import re
+
+        start = None
+        end = None
+
+        m = re.match(r'\s*(\d+)\s*', args)
+        if m:
+            start = int(m.group(0))
+            end = start + 10
+
+        m = re.match(r'\s*(\d+)\s*,\s*(\d+)\s*', args)
+        if m:
+            start, end = map(int, m.groups())
+
+        frame = Frame.get_selected_python_frame()
+        if not frame:
+            print 'Unable to locate python frame'
+            return
+
+        pyop = frame.get_pyop()
+        if not pyop:
+            print 'Unable to read information on python frame'
+            return
+
+        filename = pyop.filename()
+        lineno = pyop.current_line_num()
+
+        if start is None:
+            start = lineno - 5
+            end = lineno + 5
+
+        if start<1:
+            start = 1
+
+        with open(filename, 'r') as f:
+            all_lines = f.readlines()
+            # start and end are 1-based, all_lines is 0-based;
+            # so [start-1:end] as a python slice gives us [start, end] as a
+            # closed interval
+            for i, line in enumerate(all_lines[start-1:end]):
+                linestr = str(i+start)
+                # Highlight current line:
+                if i + start == lineno:
+                    linestr = '>' + linestr
+                sys.stdout.write('%4s    %s' % (linestr, line))
+
+
+# ...and register the command:
+PyList()
+
+def move_in_stack(move_up):
+    '''Move up or down the stack (for the py-up/py-down command)'''
+    frame = Frame.get_selected_python_frame()
+    while frame:
+        if move_up:
+            iter_frame = frame.older()
+        else:
+            iter_frame = frame.newer()
+
+        if not iter_frame:
+            break
+
+        if iter_frame.is_evalframeex():
+            # Result:
+            iter_frame.select()
+            iter_frame.print_summary()
+            return
+
+        frame = iter_frame
+
+    if move_up:
+        print 'Unable to find an older python frame'
+    else:
+        print 'Unable to find a newer python frame'
+
+class PyUp(gdb.Command):
+    'Select and print the python stack frame that called this one (if any)'
+    def __init__(self):
+        gdb.Command.__init__ (self,
+                              "py-up",
+                              gdb.COMMAND_STACK,
+                              gdb.COMPLETE_NONE)
+
+
+    def invoke(self, args, from_tty):
+        move_in_stack(move_up=True)
+
+PyUp()
+
+class PyDown(gdb.Command):
+    'Select and print the python stack frame called by this one (if any)'
+    def __init__(self):
+        gdb.Command.__init__ (self,
+                              "py-down",
+                              gdb.COMMAND_STACK,
+                              gdb.COMPLETE_NONE)
+
+
+    def invoke(self, args, from_tty):
+        move_in_stack(move_up=False)
+
+PyDown()
+
+class PyBacktrace(gdb.Command):
+    'Display the current python frame and all the frames within its call stack (if any)'
+    def __init__(self):
+        gdb.Command.__init__ (self,
+                              "py-bt",
+                              gdb.COMMAND_STACK,
+                              gdb.COMPLETE_NONE)
+
+
+    def invoke(self, args, from_tty):
+        frame = Frame.get_selected_python_frame()
+        while frame:
+            if frame.is_evalframeex():
+                frame.print_summary()
+            frame = frame.older()
+
+PyBacktrace()
+
+class PyPrint(gdb.Command):
+    'Look up the given python variable name, and print it'
+    def __init__(self):
+        gdb.Command.__init__ (self,
+                              "py-print",
+                              gdb.COMMAND_DATA,
+                              gdb.COMPLETE_NONE)
+
+
+    def invoke(self, args, from_tty):
+        name = str(args)
+
+        frame = Frame.get_selected_python_frame()
+        if not frame:
+            print 'Unable to locate python frame'
+            return
+
+        pyop_frame = frame.get_pyop()
+        if not pyop_frame:
+            print 'Unable to read information on python frame'
+            return
+
+        pyop_var, scope = pyop_frame.get_var_by_name(name)
+
+        if pyop_var:
+            print ('%s %r = %s'
+                   % (scope,
+                      name,
+                      pyop_var.get_truncated_repr(MAX_OUTPUT_LEN)))
+        else:
+            print '%r not found' % name
+
+PyPrint()
+
+class PyLocals(gdb.Command):
+    'Look up the given python variable name, and print it'
+    def __init__(self):
+        gdb.Command.__init__ (self,
+                              "py-locals",
+                              gdb.COMMAND_DATA,
+                              gdb.COMPLETE_NONE)
+
+
+    def invoke(self, args, from_tty):
+        name = str(args)
+
+        frame = Frame.get_selected_python_frame()
+        if not frame:
+            print 'Unable to locate python frame'
+            return
+
+        pyop_frame = frame.get_pyop()
+        if not pyop_frame:
+            print 'Unable to read information on python frame'
+            return
+
+        for pyop_name, pyop_value in pyop_frame.iter_locals():
+            print ('%s = %s'
+                   % (pyop_name.proxyval(set()),
+                      pyop_value.get_truncated_repr(MAX_OUTPUT_LEN)))
+
+PyLocals()
