diff -r 520cb70ecb90 Lib/test/test_gdb.py --- a/Lib/test/test_gdb.py Tue Oct 04 00:00:23 2016 -0700 +++ b/Lib/test/test_gdb.py Tue Oct 04 20:23:44 2016 +0900 @@ -11,8 +11,6 @@ import sysconfig import unittest import locale -# FIXME: issue #28023 -raise unittest.SkipTest("FIXME: issue #28023, compact dict (issue #27350) broke python-gdb.py") # Is this Python configured to support threads? try: @@ -296,9 +294,8 @@ class PrettyPrintTests(DebuggerTests): 'Verify the pretty-printing of dictionaries' self.assertGdbRepr({}) self.assertGdbRepr({'foo': 'bar'}, "{'foo': 'bar'}") - # PYTHONHASHSEED is need to get the exact item order - if not sys.flags.ignore_environment: - self.assertGdbRepr({'foo': 'bar', 'douglas': 42}, "{'douglas': 42, 'foo': 'bar'}") + # Python 3.6~ preserves insertion order + self.assertGdbRepr({'foo': 'bar', 'douglas': 42}, "{'foo': 'bar', 'douglas': 42}") def test_lists(self): 'Verify the pretty-printing of lists' @@ -819,6 +816,7 @@ id(42) ) self.assertIn('Garbage-collecting', gdb_output) + @unittest.skip("FIXME: builtin method is not shown in py-bt and py-bt-full") @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") # Some older versions of gdb will fail with diff -r 520cb70ecb90 Tools/gdb/libpython.py --- a/Tools/gdb/libpython.py Tue Oct 04 00:00:23 2016 -0700 +++ b/Tools/gdb/libpython.py Tue Oct 04 20:23:44 2016 +0900 @@ -666,8 +666,9 @@ class PyDictObjectPtr(PyObjectPtr): ''' keys = self.field('ma_keys') values = self.field('ma_values') - for i in safe_range(keys['dk_size']): - ep = keys['dk_entries'].address + i + entries, nentries = self._get_entries(keys) + for i in safe_range(nentries): + ep = entries[i] if long(values): pyop_value = PyObjectPtr.from_pyobject_ptr(values[i]) else: @@ -707,6 +708,29 @@ class PyDictObjectPtr(PyObjectPtr): pyop_value.write_repr(out, visited) out.write('}') + def _get_entries(self, keys): + dk_size = int(keys['dk_size']) + try: + # ~ Python 3.5 + return keys['dk_entries'], dk_size + except gdb.error: + # Python 3.6~ + pass + + if dk_size <= 0x80: + offset = dk_size + elif dk_size <= 0x8000: + offset = 2 * dk_size + elif dk_size <= 0x80000000: + offset = 4 * dk_size + else: + offset = 8 * dk_size + + ent_ptr_t = gdb.lookup_type('PyDictKeyEntry').pointer() + ent_addr = int(keys['dk_indices']['as_1'].address) + offset + return gdb.Value(ent_addr).cast(ent_ptr_t), int(keys['dk_nentries']) + + class PyListObjectPtr(PyObjectPtr): _typename = 'PyListObject'