Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b17d2aa

Browse files
committed
Issue #19308: fix the gdb plugin on gdbs linked with Python 3
1 parent c17565e commit b17d2aa

2 files changed

Lines changed: 70 additions & 53 deletions

File tree

Lib/test/test_gdb.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def run_gdb(*args, **env_vars):
5959
return out.decode('utf-8', 'replace'), err.decode('utf-8', 'replace')
6060

6161
# Verify that "gdb" was built with the embedded python support enabled:
62-
gdbpy_version, _ = run_gdb("--eval-command=python import sys; print sys.version_info")
62+
gdbpy_version, _ = run_gdb("--eval-command=python import sys; print(sys.version_info)")
6363
if not gdbpy_version:
6464
raise unittest.SkipTest("gdb not built with embedded python support")
6565

Tools/gdb/libpython.py

Lines changed: 69 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,21 @@
4040
4141
The module also extends gdb with some python-specific commands.
4242
'''
43-
from __future__ import with_statement
43+
44+
# NOTE: some gdbs are linked with Python 3, so this file should be dual-syntax
45+
# compatible (2.6+ and 3.0+). See #19308.
46+
47+
from __future__ import print_function, with_statement
4448
import gdb
49+
import os
4550
import locale
4651
import sys
4752

53+
if sys.version_info[0] >= 3:
54+
unichr = chr
55+
xrange = range
56+
long = int
57+
4858
# Look up the gdb.Type for some standard types:
4959
_type_char_ptr = gdb.lookup_type('char').pointer() # char*
5060
_type_unsigned_char_ptr = gdb.lookup_type('unsigned char').pointer() # unsigned char*
@@ -58,16 +68,16 @@
5868
SIZEOF_VOID_P = _type_void_ptr.sizeof
5969

6070

61-
Py_TPFLAGS_HEAPTYPE = (1L << 9)
71+
Py_TPFLAGS_HEAPTYPE = (1 << 9)
6272

63-
Py_TPFLAGS_LONG_SUBCLASS = (1L << 24)
64-
Py_TPFLAGS_LIST_SUBCLASS = (1L << 25)
65-
Py_TPFLAGS_TUPLE_SUBCLASS = (1L << 26)
66-
Py_TPFLAGS_BYTES_SUBCLASS = (1L << 27)
67-
Py_TPFLAGS_UNICODE_SUBCLASS = (1L << 28)
68-
Py_TPFLAGS_DICT_SUBCLASS = (1L << 29)
69-
Py_TPFLAGS_BASE_EXC_SUBCLASS = (1L << 30)
70-
Py_TPFLAGS_TYPE_SUBCLASS = (1L << 31)
73+
Py_TPFLAGS_LONG_SUBCLASS = (1 << 24)
74+
Py_TPFLAGS_LIST_SUBCLASS = (1 << 25)
75+
Py_TPFLAGS_TUPLE_SUBCLASS = (1 << 26)
76+
Py_TPFLAGS_BYTES_SUBCLASS = (1 << 27)
77+
Py_TPFLAGS_UNICODE_SUBCLASS = (1 << 28)
78+
Py_TPFLAGS_DICT_SUBCLASS = (1 << 29)
79+
Py_TPFLAGS_BASE_EXC_SUBCLASS = (1 << 30)
80+
Py_TPFLAGS_TYPE_SUBCLASS = (1 << 31)
7181

7282

7383
MAX_OUTPUT_LEN=1024
@@ -90,32 +100,39 @@ def safety_limit(val):
90100
def safe_range(val):
91101
# As per range, but don't trust the value too much: cap it to a safety
92102
# threshold in case the data was corrupted
93-
return xrange(safety_limit(val))
94-
95-
def write_unicode(file, text):
96-
# Write a byte or unicode string to file. Unicode strings are encoded to
97-
# ENCODING encoding with 'backslashreplace' error handler to avoid
98-
# UnicodeEncodeError.
99-
if isinstance(text, unicode):
100-
text = text.encode(ENCODING, 'backslashreplace')
101-
file.write(text)
102-
103-
def os_fsencode(filename):
104-
if not isinstance(filename, unicode):
105-
return filename
106-
encoding = sys.getfilesystemencoding()
107-
if encoding == 'mbcs':
108-
# mbcs doesn't support surrogateescape
109-
return filename.encode(encoding)
110-
encoded = []
111-
for char in filename:
112-
# surrogateescape error handler
113-
if 0xDC80 <= ord(char) <= 0xDCFF:
114-
byte = chr(ord(char) - 0xDC00)
115-
else:
116-
byte = char.encode(encoding)
117-
encoded.append(byte)
118-
return ''.join(encoded)
103+
return xrange(safety_limit(int(val)))
104+
105+
if sys.version_info[0] >= 3:
106+
def write_unicode(file, text):
107+
file.write(text)
108+
else:
109+
def write_unicode(file, text):
110+
# Write a byte or unicode string to file. Unicode strings are encoded to
111+
# ENCODING encoding with 'backslashreplace' error handler to avoid
112+
# UnicodeEncodeError.
113+
if isinstance(text, unicode):
114+
text = text.encode(ENCODING, 'backslashreplace')
115+
file.write(text)
116+
117+
try:
118+
os_fsencode = os.fsencode
119+
except ImportError:
120+
def os_fsencode(filename):
121+
if not isinstance(filename, unicode):
122+
return filename
123+
encoding = sys.getfilesystemencoding()
124+
if encoding == 'mbcs':
125+
# mbcs doesn't support surrogateescape
126+
return filename.encode(encoding)
127+
encoded = []
128+
for char in filename:
129+
# surrogateescape error handler
130+
if 0xDC80 <= ord(char) <= 0xDCFF:
131+
byte = chr(ord(char) - 0xDC00)
132+
else:
133+
byte = char.encode(encoding)
134+
encoded.append(byte)
135+
return ''.join(encoded)
119136

120137
class StringTruncated(RuntimeError):
121138
pass
@@ -322,8 +339,8 @@ def subclass_from_type(cls, t):
322339
# class
323340
return cls
324341

325-
#print 'tp_flags = 0x%08x' % tp_flags
326-
#print 'tp_name = %r' % tp_name
342+
#print('tp_flags = 0x%08x' % tp_flags)
343+
#print('tp_name = %r' % tp_name)
327344

328345
name_map = {'bool': PyBoolObjectPtr,
329346
'classobj': PyClassObjectPtr,
@@ -733,14 +750,14 @@ def proxyval(self, visited):
733750
'''
734751
ob_size = long(self.field('ob_size'))
735752
if ob_size == 0:
736-
return 0L
753+
return 0
737754

738755
ob_digit = self.field('ob_digit')
739756

740757
if gdb.lookup_type('digit').sizeof == 2:
741-
SHIFT = 15L
758+
SHIFT = 15
742759
else:
743-
SHIFT = 30L
760+
SHIFT = 30
744761

745762
digits = [long(ob_digit[i]) * 2**(SHIFT*i)
746763
for i in safe_range(abs(ob_size))]
@@ -1595,12 +1612,12 @@ def invoke(self, args, from_tty):
15951612
# py-list requires an actual PyEval_EvalFrameEx frame:
15961613
frame = Frame.get_selected_bytecode_frame()
15971614
if not frame:
1598-
print 'Unable to locate gdb frame for python bytecode interpreter'
1615+
print('Unable to locate gdb frame for python bytecode interpreter')
15991616
return
16001617

16011618
pyop = frame.get_pyop()
16021619
if not pyop or pyop.is_optimized_out():
1603-
print 'Unable to read information on python frame'
1620+
print('Unable to read information on python frame')
16041621
return
16051622

16061623
filename = pyop.filename()
@@ -1656,9 +1673,9 @@ def move_in_stack(move_up):
16561673
frame = iter_frame
16571674

16581675
if move_up:
1659-
print 'Unable to find an older python frame'
1676+
print('Unable to find an older python frame')
16601677
else:
1661-
print 'Unable to find a newer python frame'
1678+
print('Unable to find a newer python frame')
16621679

16631680
class PyUp(gdb.Command):
16641681
'Select and print the python stack frame that called this one (if any)'
@@ -1740,23 +1757,23 @@ def invoke(self, args, from_tty):
17401757

17411758
frame = Frame.get_selected_python_frame()
17421759
if not frame:
1743-
print 'Unable to locate python frame'
1760+
print('Unable to locate python frame')
17441761
return
17451762

17461763
pyop_frame = frame.get_pyop()
17471764
if not pyop_frame:
1748-
print 'Unable to read information on python frame'
1765+
print('Unable to read information on python frame')
17491766
return
17501767

17511768
pyop_var, scope = pyop_frame.get_var_by_name(name)
17521769

17531770
if pyop_var:
1754-
print ('%s %r = %s'
1771+
print('%s %r = %s'
17551772
% (scope,
17561773
name,
17571774
pyop_var.get_truncated_repr(MAX_OUTPUT_LEN)))
17581775
else:
1759-
print '%r not found' % name
1776+
print('%r not found' % name)
17601777

17611778
PyPrint()
17621779

@@ -1774,16 +1791,16 @@ def invoke(self, args, from_tty):
17741791

17751792
frame = Frame.get_selected_python_frame()
17761793
if not frame:
1777-
print 'Unable to locate python frame'
1794+
print('Unable to locate python frame')
17781795
return
17791796

17801797
pyop_frame = frame.get_pyop()
17811798
if not pyop_frame:
1782-
print 'Unable to read information on python frame'
1799+
print('Unable to read information on python frame')
17831800
return
17841801

17851802
for pyop_name, pyop_value in pyop_frame.iter_locals():
1786-
print ('%s = %s'
1803+
print('%s = %s'
17871804
% (pyop_name.proxyval(set()),
17881805
pyop_value.get_truncated_repr(MAX_OUTPUT_LEN)))
17891806

0 commit comments

Comments
 (0)