Skip to content

[3.7] bpo-40019: Skip test_gdb if Python was optimized (GH-19081) #19256

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
Mar 31, 2020
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
9 changes: 9 additions & 0 deletions Lib/test/test_gdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,15 @@ def get_stack_trace(self, source=None, script=None,
" because the Program Counter is"
" not present")

# bpo-40019: Skip the test if gdb failed to read debug information
# because the Python binary is optimized.
for pattern in (
'(frame information optimized out)',
'Unable to read information on python frame',
):
if pattern in out:
raise unittest.SkipTest(f"{pattern!r} found in gdb output")

return out

def get_gdb_repr(self, source,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
test_gdb now skips tests if it detects that gdb failed to read debug
information because the Python binary is optimized.
16 changes: 9 additions & 7 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()

FRAME_INFO_OPTIMIZED_OUT = '(frame information optimized out)'
UNABLE_READ_INFO_PYTHON_FRAME = 'Unable to read information on python frame'
EVALFRAME = '_PyEval_EvalFrameDefault'

class NullPyObjectPtr(RuntimeError):
Expand Down Expand Up @@ -918,7 +920,7 @@ def get_var_by_name(self, name):
def filename(self):
'''Get the path of the current Python source file, as a string'''
if self.is_optimized_out():
return '(frame information optimized out)'
return FRAME_INFO_OPTIMIZED_OUT
return self.co_filename.proxyval(set())

def current_line_num(self):
Expand Down Expand Up @@ -949,7 +951,7 @@ 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)'
return FRAME_INFO_OPTIMIZED_OUT

lineno = self.current_line_num()
if lineno is None:
Expand All @@ -970,7 +972,7 @@ def current_line(self):

def write_repr(self, out, visited):
if self.is_optimized_out():
out.write('(frame information optimized out)')
out.write(FRAME_INFO_OPTIMIZED_OUT)
return
lineno = self.current_line_num()
lineno = str(lineno) if lineno is not None else "?"
Expand All @@ -993,7 +995,7 @@ def write_repr(self, out, visited):

def print_traceback(self):
if self.is_optimized_out():
sys.stdout.write(' (frame information optimized out)\n')
sys.stdout.write(' %s\n' % FRAME_INFO_OPTIMIZED_OUT)
return
visited = set()
lineno = self.current_line_num()
Expand Down Expand Up @@ -1744,7 +1746,7 @@ def invoke(self, args, from_tty):

pyop = frame.get_pyop()
if not pyop or pyop.is_optimized_out():
print('Unable to read information on python frame')
print(UNABLE_READ_INFO_PYTHON_FRAME)
return

filename = pyop.filename()
Expand Down Expand Up @@ -1904,7 +1906,7 @@ def invoke(self, args, from_tty):

pyop_frame = frame.get_pyop()
if not pyop_frame:
print('Unable to read information on python frame')
print(UNABLE_READ_INFO_PYTHON_FRAME)
return

pyop_var, scope = pyop_frame.get_var_by_name(name)
Expand Down Expand Up @@ -1938,7 +1940,7 @@ def invoke(self, args, from_tty):

pyop_frame = frame.get_pyop()
if not pyop_frame:
print('Unable to read information on python frame')
print(UNABLE_READ_INFO_PYTHON_FRAME)
return

for pyop_name, pyop_value in pyop_frame.iter_locals():
Expand Down