Commit 9d95254b authored by Antoine Pitrou's avatar Antoine Pitrou

Issue #18772: fix the gdb plugin after the set implementation changes

parent f5e30d8b
...@@ -706,7 +706,6 @@ PyAPI_DATA(Py_ssize_t) _Py_RefTotal; ...@@ -706,7 +706,6 @@ PyAPI_DATA(Py_ssize_t) _Py_RefTotal;
PyAPI_FUNC(void) _Py_NegativeRefcount(const char *fname, PyAPI_FUNC(void) _Py_NegativeRefcount(const char *fname,
int lineno, PyObject *op); int lineno, PyObject *op);
PyAPI_FUNC(PyObject *) _PyDict_Dummy(void); PyAPI_FUNC(PyObject *) _PyDict_Dummy(void);
PyAPI_FUNC(PyObject *) _PySet_Dummy(void);
PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
#define _Py_INC_REFTOTAL _Py_RefTotal++ #define _Py_INC_REFTOTAL _Py_RefTotal++
#define _Py_DEC_REFTOTAL _Py_RefTotal-- #define _Py_DEC_REFTOTAL _Py_RefTotal--
......
...@@ -61,6 +61,10 @@ struct _setobject { ...@@ -61,6 +61,10 @@ struct _setobject {
PyAPI_DATA(PyTypeObject) PySet_Type; PyAPI_DATA(PyTypeObject) PySet_Type;
PyAPI_DATA(PyTypeObject) PyFrozenSet_Type; PyAPI_DATA(PyTypeObject) PyFrozenSet_Type;
PyAPI_DATA(PyTypeObject) PySetIter_Type; PyAPI_DATA(PyTypeObject) PySetIter_Type;
#ifndef Py_LIMITED_API
PyAPI_DATA(PyObject *) _PySet_Dummy;
#endif
/* Invariants for frozensets: /* Invariants for frozensets:
* data is immutable. * data is immutable.
......
...@@ -22,7 +22,7 @@ _Py_GetRefTotal(void) ...@@ -22,7 +22,7 @@ _Py_GetRefTotal(void)
o = _PyDict_Dummy(); o = _PyDict_Dummy();
if (o != NULL) if (o != NULL)
total -= o->ob_refcnt; total -= o->ob_refcnt;
o = _PySet_Dummy(); o = _PySet_Dummy;
if (o != NULL) if (o != NULL)
total -= o->ob_refcnt; total -= o->ob_refcnt;
return total; return total;
......
...@@ -29,18 +29,12 @@ set_key_error(PyObject *arg) ...@@ -29,18 +29,12 @@ set_key_error(PyObject *arg)
#define PERTURB_SHIFT 5 #define PERTURB_SHIFT 5
/* Object used as dummy key to fill deleted entries */ /* Object used as dummy key to fill deleted entries */
static PyObject _dummy_struct; static PyObject _dummy_struct;
#define dummy (&_dummy_struct) #define dummy (&_dummy_struct)
#ifdef Py_REF_DEBUG /* Exported for the gdb plugin's benefit. */
PyObject * PyObject *_PySet_Dummy = dummy;
_PySet_Dummy(void)
{
return dummy;
}
#endif
#define INIT_NONZERO_SET_SLOTS(so) do { \ #define INIT_NONZERO_SET_SLOTS(so) do { \
(so)->table = (so)->smalltable; \ (so)->table = (so)->smalltable; \
......
...@@ -922,21 +922,26 @@ class PyFrameObjectPtr(PyObjectPtr): ...@@ -922,21 +922,26 @@ class PyFrameObjectPtr(PyObjectPtr):
class PySetObjectPtr(PyObjectPtr): class PySetObjectPtr(PyObjectPtr):
_typename = 'PySetObject' _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): def proxyval(self, visited):
# Guard against infinite loops: # Guard against infinite loops:
if self.as_address() in visited: if self.as_address() in visited:
return ProxyAlreadyVisited('%s(...)' % self.safe_tp_name()) return ProxyAlreadyVisited('%s(...)' % self.safe_tp_name())
visited.add(self.as_address()) visited.add(self.as_address())
members = [] members = (key.proxyval(visited) for key in self)
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': if self.safe_tp_name() == 'frozenset':
return frozenset(members) return frozenset(members)
else: else:
...@@ -965,18 +970,11 @@ class PySetObjectPtr(PyObjectPtr): ...@@ -965,18 +970,11 @@ class PySetObjectPtr(PyObjectPtr):
out.write('{') out.write('{')
first = True first = True
table = self.field('table') for key in self:
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: if not first:
out.write(', ') out.write(', ')
first = False first = False
pyop_key.write_repr(out, visited) key.write_repr(out, visited)
out.write('}') out.write('}')
if tp_name != 'set': if tp_name != 'set':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment