]> granicus.if.org Git - python/commitdiff
Issue #18772: fix the gdb plugin after the set implementation changes
authorAntoine Pitrou <solipsis@pitrou.net>
Sat, 24 Aug 2013 19:07:07 +0000 (21:07 +0200)
committerAntoine Pitrou <solipsis@pitrou.net>
Sat, 24 Aug 2013 19:07:07 +0000 (21:07 +0200)
Include/object.h
Include/setobject.h
Objects/object.c
Objects/setobject.c
Tools/gdb/libpython.py

index 25b96e8188c7bd2f67e088467d1962471f3803df..7f3fdb089738c72368ef6a1e1f69cc154965262a 100644 (file)
@@ -706,7 +706,6 @@ PyAPI_DATA(Py_ssize_t) _Py_RefTotal;
 PyAPI_FUNC(void) _Py_NegativeRefcount(const char *fname,
                                             int lineno, PyObject *op);
 PyAPI_FUNC(PyObject *) _PyDict_Dummy(void);
-PyAPI_FUNC(PyObject *) _PySet_Dummy(void);
 PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
 #define _Py_INC_REFTOTAL        _Py_RefTotal++
 #define _Py_DEC_REFTOTAL        _Py_RefTotal--
index cbb21a17769946d3f5b765d0110b734d8d0b21e7..f377a738a8d60c10ad113941d1430173f0bd2363 100644 (file)
@@ -61,6 +61,10 @@ struct _setobject {
 PyAPI_DATA(PyTypeObject) PySet_Type;
 PyAPI_DATA(PyTypeObject) PyFrozenSet_Type;
 PyAPI_DATA(PyTypeObject) PySetIter_Type;
+#ifndef Py_LIMITED_API
+PyAPI_DATA(PyObject *) _PySet_Dummy;
+#endif
+
 
 /* Invariants for frozensets:
  *     data is immutable.
index 81d6d4b8385e7d3a123f0ef085f553ab80b79cc3..0561e09f8641021529ed79303ea26a4c8584e9ef 100644 (file)
@@ -22,7 +22,7 @@ _Py_GetRefTotal(void)
     o = _PyDict_Dummy();
     if (o != NULL)
         total -= o->ob_refcnt;
-    o = _PySet_Dummy();
+    o = _PySet_Dummy;
     if (o != NULL)
         total -= o->ob_refcnt;
     return total;
index 8a855a3bd949509320fe00d0da4ad03f7b2ab7bf..1ad78c4deb3711257ac5c63fbad334e2f07c6711 100644 (file)
@@ -29,18 +29,12 @@ set_key_error(PyObject *arg)
 #define PERTURB_SHIFT 5
 
 /* Object used as dummy key to fill deleted entries */
-
 static PyObject _dummy_struct;
 
 #define dummy (&_dummy_struct)
 
-#ifdef Py_REF_DEBUG
-PyObject *
-_PySet_Dummy(void)
-{
-    return dummy;
-}
-#endif
+/* Exported for the gdb plugin's benefit. */
+PyObject *_PySet_Dummy = dummy;
 
 #define INIT_NONZERO_SET_SLOTS(so) do {                         \
     (so)->table = (so)->smalltable;                             \
index ef69359d1ef837375d48e9db7eb1eb3c54aa3e04..684713fe22dfc9263ff310279bfc3e62f371b298 100644 (file)
@@ -922,21 +922,26 @@ class PyFrameObjectPtr(PyObjectPtr):
 class PySetObjectPtr(PyObjectPtr):
     _typename = 'PySetObject'
 
+    @classmethod
+    def _dummy_key(self):
+        return gdb.lookup_global_symbol('_PySet_Dummy').value()
+
+    def __iter__(self):
+        dummy_ptr = self._dummy_key()
+        table = self.field('table')
+        for i in safe_range(self.field('mask') + 1):
+            setentry = table[i]
+            key = setentry['key']
+            if key != 0 and key != dummy_ptr:
+                yield PyObjectPtr.from_pyobject_ptr(key)
+
     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)
+        members = (key.proxyval(visited) for key in self)
         if self.safe_tp_name() == 'frozenset':
             return frozenset(members)
         else:
@@ -965,18 +970,11 @@ class PySetObjectPtr(PyObjectPtr):
 
         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)
+        for key in self:
+            if not first:
+                out.write(', ')
+            first = False
+            key.write_repr(out, visited)
         out.write('}')
 
         if tp_name != 'set':