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

Skip to content

bpo-30983: [gdb] Fix py-bt, etc. for non-debug shared builds #3153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,7 @@ Berker Peksag
Andreas Pelme
Steven Pemberton
Bo Peng
Bruno "Polaco" Penteado
Santiago Peresón
George Peristerakis
Thomas Perl
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
gdb integration commands (py-bt, etc.) work on optimized shared builds now,
too. PEP 523 introduced _PyEval_EvalFrameDefault which inlines
PyEval_EvalFrameEx on non-debug shared builds. This broke the ability to
use py-bt, py-up, and a few other Python-specific gdb integrations. The
problem is fixed by only looking for _PyEval_EvalFrameDefault frames in
python-gdb.py. Original patch by Bruno "Polaco" Penteado.
20 changes: 11 additions & 9 deletions Tools/gdb/libpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ def _sizeof_void_p():

ENCODING = locale.getpreferredencoding()

EVALFRAME = '_PyEval_EvalFrameDefault'

class NullPyObjectPtr(RuntimeError):
pass

Expand Down Expand Up @@ -1492,18 +1494,18 @@ def get_index(self):
# - everything else

def is_python_frame(self):
'''Is this a PyEval_EvalFrameEx frame, or some other important
'''Is this a _PyEval_EvalFrameDefault frame, or some other important
frame? (see is_other_python_frame for what "important" means in this
context)'''
if self.is_evalframeex():
if self.is_evalframe():
return True
if self.is_other_python_frame():
return True
return False

def is_evalframeex(self):
'''Is this a PyEval_EvalFrameEx frame?'''
if self._gdbframe.name() == 'PyEval_EvalFrameEx':
def is_evalframe(self):
'''Is this a _PyEval_EvalFrameDefault frame?'''
if self._gdbframe.name() == EVALFRAME:
'''
I believe we also need to filter on the inline
struct frame_id.inline_depth, only regarding frames with
Expand All @@ -1512,7 +1514,7 @@ def is_evalframeex(self):
So we reject those with type gdb.INLINE_FRAME
'''
if self._gdbframe.type() == gdb.NORMAL_FRAME:
# We have a PyEval_EvalFrameEx frame:
# We have a _PyEval_EvalFrameDefault frame:
return True

return False
Expand Down Expand Up @@ -1626,15 +1628,15 @@ def get_selected_bytecode_frame(cls):
frame = cls.get_selected_frame()

while frame:
if frame.is_evalframeex():
if frame.is_evalframe():
return frame
frame = frame.older()

# Not found:
return None

def print_summary(self):
if self.is_evalframeex():
if self.is_evalframe():
pyop = self.get_pyop()
if pyop:
line = pyop.get_truncated_repr(MAX_OUTPUT_LEN)
Expand All @@ -1653,7 +1655,7 @@ def print_summary(self):
sys.stdout.write('#%i\n' % self.get_index())

def print_traceback(self):
if self.is_evalframeex():
if self.is_evalframe():
pyop = self.get_pyop()
if pyop:
pyop.print_traceback()
Expand Down