Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
c6807afd
Commit
c6807afd
authored
Mar 31, 2019
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update libpython from latest CPython upstream (1ceb3a3d17).
parent
4eef0edd
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
67 additions
and
33 deletions
+67
-33
Cython/Debugger/libpython.py
Cython/Debugger/libpython.py
+67
-33
No files found.
Cython/Debugger/libpython.py
View file @
c6807afd
...
...
@@ -9,7 +9,7 @@
From gdb 7 onwards, gdb's build can be configured --with-python, allowing gdb
to be extended with Python code e.g. for library-specific data visualizations,
such as for the C++ STL types. Documentation on this API can be seen at:
http
s
://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html
http://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html
This python module deals with the case when the process being debugged (the
...
...
@@ -48,7 +48,7 @@ The module also extends gdb with some python-specific commands.
'''
# NOTE: some gdbs are linked with Python 3, so this file should be dual-syntax
# compatible (2.
7+ and 3.3
+). See #19308.
# compatible (2.
6+ and 3.0
+). See #19308.
from
__future__
import
print_function
import
gdb
...
...
@@ -276,12 +276,13 @@ class PyObjectPtr(object):
def
safe_tp_name
(
self
):
try
:
return
self
.
type
().
field
(
'tp_name'
).
string
()
except
NullPyObjectPtr
:
# NULL tp_name?
return
'unknown'
except
RuntimeError
:
# Can't even read the object at all?
ob_type
=
self
.
type
()
tp_name
=
ob_type
.
field
(
'tp_name'
)
return
tp_name
.
string
()
# NullPyObjectPtr: NULL tp_name?
# RuntimeError: Can't even read the object at all?
# UnicodeDecodeError: Failed to decode tp_name bytestring
except
(
NullPyObjectPtr
,
RuntimeError
,
UnicodeDecodeError
):
return
'unknown'
def
proxyval
(
self
,
visited
):
...
...
@@ -315,7 +316,7 @@ class PyObjectPtr(object):
def
__repr__
(
self
):
# For the NULL pointer, we have no way of knowing a type, so
# special-case it as per
# http
s
://bugs.python.org/issue8032#msg100882
# http://bugs.python.org/issue8032#msg100882
if
self
.
address
==
0
:
return
'0x0'
return
'<%s at remote 0x%x>'
%
(
self
.
tp_name
,
self
.
address
)
...
...
@@ -355,7 +356,9 @@ class PyObjectPtr(object):
try
:
tp_name
=
t
.
field
(
'tp_name'
).
string
()
tp_flags
=
int
(
t
.
field
(
'tp_flags'
))
except
RuntimeError
:
# RuntimeError: NULL pointers
# UnicodeDecodeError: string() fails to decode the bytestring
except
(
RuntimeError
,
UnicodeDecodeError
):
# Handle any kind of error e.g. NULL ptrs by simply using the base
# class
return
cls
...
...
@@ -623,7 +626,10 @@ class PyCFunctionObjectPtr(PyObjectPtr):
def
proxyval
(
self
,
visited
):
m_ml
=
self
.
field
(
'm_ml'
)
# m_ml is a (PyMethodDef*)
try
:
ml_name
=
m_ml
[
'ml_name'
].
string
()
except
UnicodeDecodeError
:
ml_name
=
'<ml_name:UnicodeDecodeError>'
pyop_m_self
=
self
.
pyop_field
(
'm_self'
)
if
pyop_m_self
.
is_null
():
...
...
@@ -736,7 +742,7 @@ class PyDictObjectPtr(PyObjectPtr):
else
:
offset
=
8
*
dk_size
ent_addr
=
keys
[
'dk_indices'
]
[
'as_1'
]
.
address
ent_addr
=
keys
[
'dk_indices'
].
address
ent_addr
=
ent_addr
.
cast
(
_type_unsigned_char_ptr
())
+
offset
ent_ptr_t
=
gdb
.
lookup_type
(
'PyDictKeyEntry'
).
pointer
()
ent_addr
=
ent_addr
.
cast
(
ent_ptr_t
)
...
...
@@ -934,35 +940,50 @@ class PyFrameObjectPtr(PyObjectPtr):
if
long
(
f_trace
)
!=
0
:
# we have a non-NULL f_trace:
return
self
.
f_lineno
else
:
#
try:
try
:
return
self
.
co
.
addr2line
(
self
.
f_lasti
)
#except ValueError:
# return self.f_lineno
except
Exception
:
# bpo-34989: addr2line() is a complex function, it can fail in many
# ways. For example, it fails with a TypeError on "FakeRepr" if
# gdb fails to load debug symbols. Use a catch-all "except
# Exception" to make the whole function safe. The caller has to
# handle None anyway for optimized Python.
return
None
def
current_line
(
self
):
'''Get the text of the current source line as a string, with a trailing
newline character'''
if
self
.
is_optimized_out
():
return
'(frame information optimized out)'
lineno
=
self
.
current_line_num
()
if
lineno
is
None
:
return
'(failed to get frame line number)'
filename
=
self
.
filename
()
try
:
f
=
open
(
os_fsencode
(
filename
),
'r'
)
with
open
(
os_fsencode
(
filename
),
'r'
)
as
fp
:
lines
=
fp
.
readlines
()
except
IOError
:
return
None
with
f
:
all_lines
=
f
.
readlines
()
# Convert from 1-based current_line_num to 0-based list offset:
return
all_lines
[
self
.
current_line_num
()
-
1
]
try
:
# Convert from 1-based current_line_num to 0-based list offset
return
lines
[
lineno
-
1
]
except
IndexError
:
return
None
def
write_repr
(
self
,
out
,
visited
):
if
self
.
is_optimized_out
():
out
.
write
(
'(frame information optimized out)'
)
return
out
.
write
(
'Frame 0x%x, for file %s, line %i, in %s ('
lineno
=
self
.
current_line_num
()
lineno
=
str
(
lineno
)
if
lineno
is
not
None
else
"?"
out
.
write
(
'Frame 0x%x, for file %s, line %s, in %s ('
%
(
self
.
as_address
(),
self
.
co_filename
.
proxyval
(
visited
),
self
.
current_line_num
()
,
lineno
,
self
.
co_name
.
proxyval
(
visited
)))
first
=
True
for
pyop_name
,
pyop_value
in
self
.
iter_locals
():
...
...
@@ -981,9 +1002,11 @@ class PyFrameObjectPtr(PyObjectPtr):
sys
.
stdout
.
write
(
' (frame information optimized out)
\
n
'
)
return
visited
=
set
()
sys
.
stdout
.
write
(
' File "%s", line %i, in %s
\
n
'
lineno
=
self
.
current_line_num
()
lineno
=
str
(
lineno
)
if
lineno
is
not
None
else
"?"
sys
.
stdout
.
write
(
' File "%s", line %s, in %s
\
n
'
%
(
self
.
co_filename
.
proxyval
(
visited
),
self
.
current_line_num
()
,
lineno
,
self
.
co_name
.
proxyval
(
visited
)))
class
PySetObjectPtr
(
PyObjectPtr
):
...
...
@@ -1092,6 +1115,7 @@ class PyBytesObjectPtr(PyObjectPtr):
out
.
write
(
quote
)
# Added in Cython for Py2 backwards compatibility.
class
PyStringObjectPtr
(
PyBytesObjectPtr
):
_typename
=
'PyStringObject'
...
...
@@ -1166,7 +1190,7 @@ class PyUnicodeObjectPtr(PyObjectPtr):
def
proxyval
(
self
,
visited
):
global
_is_pep393
if
_is_pep393
is
None
:
fields
=
gdb
.
lookup_type
(
'PyUnicodeObject'
).
target
().
fields
()
fields
=
gdb
.
lookup_type
(
'PyUnicodeObject'
).
fields
()
_is_pep393
=
'data'
in
[
f
.
name
for
f
in
fields
]
if
_is_pep393
:
# Python 3.3 and newer
...
...
@@ -1351,13 +1375,13 @@ class wrapperobject(PyObjectPtr):
try
:
name
=
self
.
field
(
'descr'
)[
'd_base'
][
'name'
].
string
()
return
repr
(
name
)
except
(
NullPyObjectPtr
,
RuntimeError
):
except
(
NullPyObjectPtr
,
RuntimeError
,
UnicodeDecodeError
):
return
'<unknown name>'
def
safe_tp_name
(
self
):
try
:
return
self
.
field
(
'self'
)[
'ob_type'
][
'tp_name'
].
string
()
except
(
NullPyObjectPtr
,
RuntimeError
):
except
(
NullPyObjectPtr
,
RuntimeError
,
UnicodeDecodeError
):
return
'<unknown tp_name>'
def
safe_self_addresss
(
self
):
...
...
@@ -1435,8 +1459,8 @@ The following code should ensure that the prettyprinter is registered
if the code is autoloaded by gdb when visiting libpython.so, provided
that this python file is installed to the same path as the library (or its
.debug file) plus a "-gdb.py" suffix, e.g:
/usr/lib/libpython
3.7
.so.1.0-gdb.py
/usr/lib/debug/usr/lib/libpython
3.7
.so.1.0.debug-gdb.py
/usr/lib/libpython
2.6
.so.1.0-gdb.py
/usr/lib/debug/usr/lib/libpython
2.6
.so.1.0.debug-gdb.py
"""
def
register
(
obj
):
if
obj
is
None
:
...
...
@@ -1451,7 +1475,7 @@ register (gdb.current_objfile ())
# Unfortunately, the exact API exposed by the gdb module varies somewhat
# from build to build
# See http
s
://bugs.python.org/issue8279?#msg102276
# See http://bugs.python.org/issue8279?#msg102276
class
Frame
(
object
):
'''
...
...
@@ -1563,15 +1587,22 @@ class Frame(object):
# Use the prettyprinter for the func:
func
=
frame
.
read_var
(
arg_name
)
return
str
(
func
)
except
ValueError
:
return
(
'PyCFunction invocation (unable to read %s: '
'missing debuginfos?)'
%
arg_name
)
except
RuntimeError
:
return
'PyCFunction invocation (unable to read %s)'
%
arg_name
if
caller
==
'wrapper_call'
:
arg_name
=
'wp'
try
:
func
=
frame
.
read_var
(
'wp'
)
func
=
frame
.
read_var
(
arg_name
)
return
str
(
func
)
except
ValueError
:
return
(
'<wrapper_call invocation (unable to read %s: '
'missing debuginfos?)>'
%
arg_name
)
except
RuntimeError
:
return
'<wrapper_call invocation
>'
return
'<wrapper_call invocation
(unable to read %s)>'
%
arg_name
# This frame isn't worth reporting:
return
False
...
...
@@ -1730,6 +1761,9 @@ class PyList(gdb.Command):
filename = pyop.filename()
lineno = pyop.current_line_num()
if lineno is None:
print('
Unable
to
read
python
frame
line
number
')
return
if start is None:
start = lineno - 5
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment