summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_gdb.py19
-rw-r--r--Misc/NEWS2
-rw-r--r--Tools/gdb/libpython.py30
3 files changed, 36 insertions, 15 deletions
diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py
index b01efcb..907d6ef 100644
--- a/Lib/test/test_gdb.py
+++ b/Lib/test/test_gdb.py
@@ -31,6 +31,19 @@ gdbpy_version, _ = p.communicate()
if gdbpy_version == '':
raise unittest.SkipTest("gdb not built with embedded python support")
+def gdb_has_frame_select():
+ # Does this build of gdb have gdb.Frame.select ?
+ cmd = "--eval-command=python print(dir(gdb.Frame))"
+ p = subprocess.Popen(["gdb", "--batch", cmd],
+ stdout=subprocess.PIPE)
+ stdout, _ = p.communicate()
+ m = re.match(r'.*\[(.*)\].*', stdout)
+ if not m:
+ raise unittest.SkipTest("Unable to parse output from gdb.Frame.select test")
+ gdb_frame_dir = m.group(1).split(', ')
+ return "'select'" in gdb_frame_dir
+
+HAS_PYUP_PYDOWN = gdb_has_frame_select()
class DebuggerTests(unittest.TestCase):
@@ -569,6 +582,7 @@ class PyListTests(DebuggerTests):
bt)
class StackNavigationTests(DebuggerTests):
+ @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
def test_pyup_command(self):
'Verify that the "py-up" command works'
bt = self.get_stack_trace(script=self.get_sample_script(),
@@ -579,6 +593,7 @@ class StackNavigationTests(DebuggerTests):
baz\(a, b, c\)
$''')
+ @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
def test_down_at_bottom(self):
'Verify handling of "py-down" at the bottom of the stack'
bt = self.get_stack_trace(script=self.get_sample_script(),
@@ -586,6 +601,7 @@ $''')
self.assertEndsWith(bt,
'Unable to find a newer python frame\n')
+ @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
def test_up_at_top(self):
'Verify handling of "py-up" at the top of the stack'
bt = self.get_stack_trace(script=self.get_sample_script(),
@@ -593,6 +609,7 @@ $''')
self.assertEndsWith(bt,
'Unable to find an older python frame\n')
+ @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
def test_up_then_down(self):
'Verify "py-up" followed by "py-down"'
bt = self.get_stack_trace(script=self.get_sample_script(),
@@ -628,6 +645,7 @@ class PyPrintTests(DebuggerTests):
self.assertMultilineMatches(bt,
r".*\nlocal 'args' = \(1, 2, 3\)\n.*")
+ @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
def test_print_after_up(self):
bt = self.get_stack_trace(script=self.get_sample_script(),
cmds_after_breakpoint=['py-up', 'py-print c', 'py-print b', 'py-print a'])
@@ -653,6 +671,7 @@ class PyLocalsTests(DebuggerTests):
self.assertMultilineMatches(bt,
r".*\nargs = \(1, 2, 3\)\n.*")
+ @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
def test_locals_after_up(self):
bt = self.get_stack_trace(script=self.get_sample_script(),
cmds_after_breakpoint=['py-up', 'py-locals'])
diff --git a/Misc/NEWS b/Misc/NEWS
index 9eecb10..d03a475 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -20,6 +20,8 @@ Core and Builtins
Library
-------
+- Issue #8437: Fix test_gdb failures, patch written by Dave Malcolm
+
- Issue #4814: timeout parameter is now applied also for connections resulting
from PORT/EPRT commands.
diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py
index 7726020..f62735f 100644
--- a/Tools/gdb/libpython.py
+++ b/Tools/gdb/libpython.py
@@ -1148,18 +1148,17 @@ class Frame(object):
def is_evalframeex(self):
'''Is this a PyEval_EvalFrameEx frame?'''
- if self._gdbframe.function():
- if self._gdbframe.name() == 'PyEval_EvalFrameEx':
- '''
- I believe we also need to filter on the inline
- struct frame_id.inline_depth, only regarding frames with
- an inline depth of 0 as actually being this function
-
- So we reject those with type gdb.INLINE_FRAME
- '''
- if self._gdbframe.type() == gdb.NORMAL_FRAME:
- # We have a PyEval_EvalFrameEx frame:
- return True
+ if self._gdbframe.name() == 'PyEval_EvalFrameEx':
+ '''
+ I believe we also need to filter on the inline
+ struct frame_id.inline_depth, only regarding frames with
+ an inline depth of 0 as actually being this function
+
+ So we reject those with type gdb.INLINE_FRAME
+ '''
+ if self._gdbframe.type() == gdb.NORMAL_FRAME:
+ # We have a PyEval_EvalFrameEx frame:
+ return True
return False
@@ -1309,8 +1308,6 @@ class PyUp(gdb.Command):
def invoke(self, args, from_tty):
move_in_stack(move_up=True)
-PyUp()
-
class PyDown(gdb.Command):
'Select and print the python stack frame called by this one (if any)'
def __init__(self):
@@ -1323,7 +1320,10 @@ class PyDown(gdb.Command):
def invoke(self, args, from_tty):
move_in_stack(move_up=False)
-PyDown()
+# Not all builds of gdb have gdb.Frame.select
+if hasattr(gdb.Frame, 'select'):
+ PyUp()
+ PyDown()
class PyBacktrace(gdb.Command):
'Display the current python frame and all the frames within its call stack (if any)'