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

Skip to content

Commit f358eaf

Browse files
committed
merge #15043: Improve test_gdb support of gdb >= 7.4.
Instead of requiring the tester to manually add the path to the python-gdb.py file in the checkout to their .gdbinit file, add it automatically when invoking gdb in the test.
2 parents 254af26 + f933302 commit f358eaf

1 file changed

Lines changed: 44 additions & 38 deletions

File tree

Lib/test/test_gdb.py

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,42 +26,58 @@
2626
# This is what "no gdb" looks like. There may, however, be other
2727
# errors that manifest this way too.
2828
raise unittest.SkipTest("Couldn't find gdb on the path")
29-
gdb_version_number = re.search(b"^GNU gdb [^\d]*(\d+)\.", gdb_version)
30-
if int(gdb_version_number.group(1)) < 7:
29+
gdb_version_number = re.search(b"^GNU gdb [^\d]*(\d+)\.(\d)", gdb_version)
30+
gdb_major_version = int(gdb_version_number.group(1))
31+
gdb_minor_version = int(gdb_version_number.group(2))
32+
if gdb_major_version < 7:
3133
raise unittest.SkipTest("gdb versions before 7.0 didn't support python embedding"
3234
" Saw:\n" + gdb_version.decode('ascii', 'replace'))
3335

3436
if not sysconfig.is_python_build():
3537
raise unittest.SkipTest("test_gdb only works on source builds at the moment.")
3638

39+
# Location of custom hooks file in a repository checkout.
40+
checkout_hook_path = os.path.join(os.path.dirname(sys.executable),
41+
'python-gdb.py')
42+
43+
def run_gdb(*args, **env_vars):
44+
"""Runs gdb in --batch mode with the additional arguments given by *args.
45+
46+
Returns its (stdout, stderr) decoded from utf-8 using the replace handler.
47+
"""
48+
if env_vars:
49+
env = os.environ.copy()
50+
env.update(env_vars)
51+
else:
52+
env = None
53+
base_cmd = ('gdb', '--batch')
54+
if (gdb_major_version, gdb_minor_version) >= (7, 4):
55+
base_cmd += ('-iex', 'add-auto-load-safe-path ' + checkout_hook_path)
56+
out, err = subprocess.Popen(base_cmd + args,
57+
stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env,
58+
).communicate()
59+
return out.decode('utf-8', 'replace'), err.decode('utf-8', 'replace')
60+
3761
# Verify that "gdb" was built with the embedded python support enabled:
38-
cmd = "--eval-command=python import sys; print sys.version_info"
39-
p = subprocess.Popen(["gdb", "--batch", cmd],
40-
stdout=subprocess.PIPE)
41-
gdbpy_version, _ = p.communicate()
42-
if gdbpy_version == b'':
62+
gdbpy_version, _ = run_gdb("--eval-command=python import sys; print sys.version_info")
63+
if not gdbpy_version:
4364
raise unittest.SkipTest("gdb not built with embedded python support")
4465

45-
# Verify that "gdb" can load our custom hooks
46-
p = subprocess.Popen(["gdb", "--batch", cmd,
47-
"--args", sys.executable],
48-
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
49-
__, gdbpy_errors = p.communicate()
50-
if b"auto-loading has been declined" in gdbpy_errors:
51-
msg = "gdb security settings prevent use of custom hooks: %s"
52-
raise unittest.SkipTest(msg % gdbpy_errors)
66+
# Verify that "gdb" can load our custom hooks. In theory this should never fail.
67+
cmd = ['--args', sys.executable]
68+
_, gdbpy_errors = run_gdb('--args', sys.executable)
69+
if "auto-loading has been declined" in gdbpy_errors:
70+
msg = "gdb security settings prevent use of custom hooks: "
71+
raise unittest.SkipTest(msg + gdbpy_errors.rstrip())
5372

5473
def gdb_has_frame_select():
5574
# Does this build of gdb have gdb.Frame.select ?
56-
cmd = "--eval-command=python print(dir(gdb.Frame))"
57-
p = subprocess.Popen(["gdb", "--batch", cmd],
58-
stdout=subprocess.PIPE)
59-
stdout, _ = p.communicate()
60-
m = re.match(br'.*\[(.*)\].*', stdout)
75+
stdout, _ = run_gdb("--eval-command=python print(dir(gdb.Frame))")
76+
m = re.match(r'.*\[(.*)\].*', stdout)
6177
if not m:
6278
raise unittest.SkipTest("Unable to parse output from gdb.Frame.select test")
63-
gdb_frame_dir = m.group(1).split(b', ')
64-
return b"'select'" in gdb_frame_dir
79+
gdb_frame_dir = m.group(1).split(', ')
80+
return "'select'" in gdb_frame_dir
6581

6682
HAS_PYUP_PYDOWN = gdb_has_frame_select()
6783

@@ -71,21 +87,6 @@ class DebuggerTests(unittest.TestCase):
7187

7288
"""Test that the debugger can debug Python."""
7389

74-
def run_gdb(self, *args, **env_vars):
75-
"""Runs gdb with the command line given by *args.
76-
77-
Returns its stdout, stderr
78-
"""
79-
if env_vars:
80-
env = os.environ.copy()
81-
env.update(env_vars)
82-
else:
83-
env = None
84-
out, err = subprocess.Popen(
85-
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env,
86-
).communicate()
87-
return out.decode('utf-8', 'replace'), err.decode('utf-8', 'replace')
88-
8990
def get_stack_trace(self, source=None, script=None,
9091
breakpoint=BREAKPOINT_FN,
9192
cmds_after_breakpoint=None,
@@ -142,7 +143,7 @@ def get_stack_trace(self, source=None, script=None,
142143
# print ' '.join(args)
143144

144145
# Use "args" to invoke gdb, capturing stdout, stderr:
145-
out, err = self.run_gdb(*args, PYTHONHASHSEED='0')
146+
out, err = run_gdb(*args, PYTHONHASHSEED='0')
146147

147148
# Ignore some noise on stderr due to the pending breakpoint:
148149
err = err.replace('Function "%s" not defined.\n' % breakpoint, '')
@@ -159,6 +160,11 @@ def get_stack_trace(self, source=None, script=None,
159160
'Do you need "set solib-search-path" or '
160161
'"set sysroot"?\n',
161162
'')
163+
err = err.replace('warning: Could not load shared library symbols for '
164+
'linux-gate.so.1.\n'
165+
'Do you need "set solib-search-path" or '
166+
'"set sysroot"?\n',
167+
'')
162168

163169
# Ensure no unexpected error messages:
164170
self.assertEqual(err, '')

0 commit comments

Comments
 (0)