From d1d013c01c268d869597b35cbcd8b5d7c5baf2ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Wed, 28 Sep 2011 07:41:54 +0200 Subject: Implement PEP 393. --- Tools/gdb/libpython.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'Tools/gdb/libpython.py') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index ca1dc60cc3..5ebbc52881 100644 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -51,6 +51,8 @@ _type_unsigned_char_ptr = gdb.lookup_type('unsigned char').pointer() # unsigned _type_void_ptr = gdb.lookup_type('void').pointer() # void* _type_size_t = gdb.lookup_type('size_t') +_is_pep393 = 'data' in [f.name for f in gdb.lookup_type('PyUnicodeObject').target().fields()] + SIZEOF_VOID_P = _type_void_ptr.sizeof @@ -1123,11 +1125,30 @@ class PyUnicodeObjectPtr(PyObjectPtr): # 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') + if _is_pep393: + # Python 3.3 and newer + may_have_surrogates = False + field_state = long(self.field('state')) + repr_kind = (field_state & 0xC) >> 2 + if repr_kind == 0: + # string is not ready + may_have_surrogates = True + field_str = self.field('wstr') + field_length = self.field('wstr_length') + elif repr_kind == 1: + field_str = self.field('data')['latin1'] + elif repr_kind == 2: + field_str = self.field('data')['ucs2'] + elif repr_kind == 3: + field_str = self.field('data')['ucs4'] + else: + # Python 3.2 and earlier + field_str = self.field('str') + may_have_surrogates = self.char_width() == 2 # Gather a list of ints from the Py_UNICODE array; these are either - # UCS-2 or UCS-4 code points: - if self.char_width() > 2: + # UCS-1, UCS-2 or UCS-4 code points: + if not may_have_surrogates: Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)] else: # A more elaborate routine if sizeof(Py_UNICODE) is 2 in the -- cgit v1.2.1 From bf49f1df00ad1966f25ee8a0baa5d9dc88bc863d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Wed, 28 Sep 2011 08:35:25 +0200 Subject: Update for PEP 393. --- Tools/gdb/libpython.py | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'Tools/gdb/libpython.py') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 5ebbc52881..b5183d45fc 100644 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -50,6 +50,8 @@ _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') +_type_unsigned_short_ptr = gdb.lookup_type('unsigned short').pointer() +_type_unsigned_int_ptr = gdb.lookup_type('unsigned int').pointer() _is_pep393 = 'data' in [f.name for f in gdb.lookup_type('PyUnicodeObject').target().fields()] @@ -1124,25 +1126,36 @@ class PyUnicodeObjectPtr(PyObjectPtr): # 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')) if _is_pep393: # Python 3.3 and newer may_have_surrogates = False - field_state = long(self.field('state')) - repr_kind = (field_state & 0xC) >> 2 - if repr_kind == 0: + compact = self.field('_base') + ascii = compact['_base'] + state = ascii['state'] + field_length = long(ascii['length']) + if not int(state['ready']): # string is not ready may_have_surrogates = True - field_str = self.field('wstr') - field_length = self.field('wstr_length') - elif repr_kind == 1: - field_str = self.field('data')['latin1'] - elif repr_kind == 2: - field_str = self.field('data')['ucs2'] - elif repr_kind == 3: - field_str = self.field('data')['ucs4'] + field_str = ascii['wstr'] + if not int(state['ascii']): + field_length = compact('wstr_length') + else: + if int(state['ascii']): + field_str = ascii.address + 1 + elif int(state['compact']): + field_str = compact.address + 1 + else: + field_str = self.field('data')['any'] + repr_kind = int(state['kind']) + if repr_kind == 1: + field_str = field_str.cast(_type_unsigned_char_ptr) + elif repr_kind == 2: + field_str = field_str.cast(_type_unsigned_short_ptr) + elif repr_kind == 3: + field_str = field_str.cast(_type_unsigned_int_ptr) else: # Python 3.2 and earlier + field_length = long(self.field('length')) field_str = self.field('str') may_have_surrogates = self.char_width() == 2 -- cgit v1.2.1 From 7e233deecbd59f88082f6fb7dad7b851236b4354 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 3 Oct 2011 13:53:37 +0200 Subject: PyUnicode_Ready() now sets ascii=1 if maxchar < 128 ascii=1 is no more reserved to PyASCIIObject. Use PyUnicode_IS_COMPACT_ASCII(obj) to check if obj is a PyASCIIObject (as before). --- Tools/gdb/libpython.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Tools/gdb/libpython.py') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index b5183d45fc..4b42c8bff8 100644 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1132,15 +1132,16 @@ class PyUnicodeObjectPtr(PyObjectPtr): compact = self.field('_base') ascii = compact['_base'] state = ascii['state'] + is_compact_ascii = (int(state['ascii']) and int(state['compact'])) field_length = long(ascii['length']) if not int(state['ready']): # string is not ready may_have_surrogates = True field_str = ascii['wstr'] - if not int(state['ascii']): + if not is_compact_ascii: field_length = compact('wstr_length') else: - if int(state['ascii']): + if is_compact_ascii: field_str = ascii.address + 1 elif int(state['compact']): field_str = compact.address + 1 -- cgit v1.2.1 From 2be03541a70ffb5abbf87666e6b8847a69868c16 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sat, 8 Oct 2011 19:33:24 +0200 Subject: Fix test_gdb following the small unicode struct change in c25262e97304 (issue #13130) --- Tools/gdb/libpython.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Tools/gdb/libpython.py') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 4b42c8bff8..43a0f20ec1 100644 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1152,7 +1152,7 @@ class PyUnicodeObjectPtr(PyObjectPtr): field_str = field_str.cast(_type_unsigned_char_ptr) elif repr_kind == 2: field_str = field_str.cast(_type_unsigned_short_ptr) - elif repr_kind == 3: + elif repr_kind == 4: field_str = field_str.cast(_type_unsigned_int_ptr) else: # Python 3.2 and earlier -- cgit v1.2.1 From 61a48f365a3791525a1a102d87ee90d950c621aa Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 4 Nov 2011 20:54:05 +0100 Subject: Fix gdb/libpython.py for not ready Unicode strings _PyUnicode_CheckConsistency() checks also hash and length value for not ready Unicode strings. --- Tools/gdb/libpython.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'Tools/gdb/libpython.py') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 43a0f20ec1..3fea68f8e3 100644 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1123,9 +1123,6 @@ class PyUnicodeObjectPtr(PyObjectPtr): return _type_Py_UNICODE.sizeof def proxyval(self, visited): - # From unicodeobject.h: - # Py_ssize_t length; /* Length of raw Unicode data in buffer */ - # Py_UNICODE *str; /* Raw Unicode buffer */ if _is_pep393: # Python 3.3 and newer may_have_surrogates = False @@ -1138,8 +1135,6 @@ class PyUnicodeObjectPtr(PyObjectPtr): # string is not ready may_have_surrogates = True field_str = ascii['wstr'] - if not is_compact_ascii: - field_length = compact('wstr_length') else: if is_compact_ascii: field_str = ascii.address + 1 -- cgit v1.2.1 From f7d16daa4c748adc0802627e3e7924760f7ebcdc Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 4 Nov 2011 22:34:01 +0100 Subject: Oops, really fix gdb/libpython.py for not ready Unicode strings --- Tools/gdb/libpython.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Tools/gdb/libpython.py') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 3fea68f8e3..1e38c26162 100644 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1130,12 +1130,13 @@ class PyUnicodeObjectPtr(PyObjectPtr): ascii = compact['_base'] state = ascii['state'] is_compact_ascii = (int(state['ascii']) and int(state['compact'])) - field_length = long(ascii['length']) if not int(state['ready']): # string is not ready + field_length = long(compact['wstr_length']) may_have_surrogates = True field_str = ascii['wstr'] else: + field_length = long(ascii['length']) if is_compact_ascii: field_str = ascii.address + 1 elif int(state['compact']): -- cgit v1.2.1 From e2e15acd7a6caa9b10f20501e75589265b0cc74e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 8 Dec 2011 00:08:22 +0100 Subject: libpython.py: defer call to gdb.lookup_type('PyUnicodeObject') The lookup fails at startup if Python is linked to a shared library. --- Tools/gdb/libpython.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Tools/gdb/libpython.py') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 1e38c26162..6972b9b1d6 100644 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -53,7 +53,8 @@ _type_size_t = gdb.lookup_type('size_t') _type_unsigned_short_ptr = gdb.lookup_type('unsigned short').pointer() _type_unsigned_int_ptr = gdb.lookup_type('unsigned int').pointer() -_is_pep393 = 'data' in [f.name for f in gdb.lookup_type('PyUnicodeObject').target().fields()] +# value computed later, see PyUnicodeObjectPtr.proxy() +_is_pep393 = None SIZEOF_VOID_P = _type_void_ptr.sizeof @@ -1123,6 +1124,10 @@ class PyUnicodeObjectPtr(PyObjectPtr): return _type_Py_UNICODE.sizeof def proxyval(self, visited): + global _is_pep393 + if _is_pep393 is None: + fields = gdb.lookup_type('PyUnicodeObject').target().fields() + _is_pep393 = 'data' in [f.name for f in fields] if _is_pep393: # Python 3.3 and newer may_have_surrogates = False -- cgit v1.2.1 From b15cf649f348f5af9bd8f38405377c5be866a6d8 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Mon, 12 Dec 2011 18:54:29 +0100 Subject: Issue #13575: there is only one class type. --- Tools/gdb/libpython.py | 44 +++----------------------------------------- 1 file changed, 3 insertions(+), 41 deletions(-) (limited to 'Tools/gdb/libpython.py') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 6972b9b1d6..0eef228c4f 100644 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -402,7 +402,7 @@ class ProxyAlreadyVisited(object): def _write_instance_repr(out, visited, name, pyop_attrdict, address): - '''Shared code for use by old-style and new-style classes: + '''Shared code for use by all classes: write a representation to file-like object "out"''' out.write('<') out.write(name) @@ -481,7 +481,7 @@ class HeapTypeObjectPtr(PyObjectPtr): def proxyval(self, visited): ''' - Support for new-style classes. + Support for classes. Currently we just locate the dictionary using a transliteration to python of _PyObject_GetDictPtr, ignoring descriptors @@ -498,7 +498,7 @@ class HeapTypeObjectPtr(PyObjectPtr): attr_dict = {} tp_name = self.safe_tp_name() - # New-style class: + # Class: return InstanceProxy(tp_name, attr_dict, long(self._gdbval)) def write_repr(self, out, visited): @@ -670,44 +670,6 @@ class PyDictObjectPtr(PyObjectPtr): 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 PyListObjectPtr(PyObjectPtr): _typename = 'PyListObject' -- cgit v1.2.1 From 8ce5ef1a1bff22c8417a08c8737e1338ab65fa80 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 12 Dec 2011 19:18:24 +0100 Subject: Fix test_gdb failure --- Tools/gdb/libpython.py | 1 - 1 file changed, 1 deletion(-) (limited to 'Tools/gdb/libpython.py') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 0eef228c4f..b6ec063c93 100644 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -328,7 +328,6 @@ class PyObjectPtr(object): name_map = {'bool': PyBoolObjectPtr, 'classobj': PyClassObjectPtr, - 'instance': PyInstanceObjectPtr, 'NoneType': PyNoneStructPtr, 'frame': PyFrameObjectPtr, 'set' : PySetObjectPtr, -- cgit v1.2.1