cpython: b71cda2f48c6 (original) (raw)
--- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -19,39 +19,57 @@ except OSError: # This is what "no gdb" looks like. There may, however, be other # errors that manifest this way too. raise unittest.SkipTest("Couldn't find gdb on the path") -gdb_version_number = re.search(b"^GNU gdb [^\d](\d+).", gdb_version) -if int(gdb_version_number.group(1)) < 7: +gdb_version_number = re.search(b"^GNU gdb [^\d](\d+).(\d)", gdb_version) +gdb_major_version = int(gdb_version_number.group(1)) +gdb_minor_version = int(gdb_version_number.group(2)) +if gdb_major_version < 7: raise unittest.SkipTest("gdb versions before 7.0 didn't support python embedding" " Saw:\n" + gdb_version.decode('ascii', 'replace')) +# Location of custom hooks file in a repository checkout. +checkout_hook_path = os.path.join(os.path.dirname(sys.executable),
'python-gdb.py')[](#l1.18)
+ +def run_gdb(*args, **env_vars):
- Returns its (stdout, stderr) decoded from utf-8 using the replace handler.
- """
- if env_vars:
env = os.environ.copy()[](#l1.26)
env.update(env_vars)[](#l1.27)
- else:
env = None[](#l1.29)
- base_cmd = ('gdb', '--batch')
- if (gdb_major_version, gdb_minor_version) >= (7, 4):
base_cmd += ('-iex', 'add-auto-load-safe-path ' + checkout_hook_path)[](#l1.32)
- out, err = subprocess.Popen(base_cmd + args,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env,[](#l1.34)
).communicate()[](#l1.35)
- return out.decode('utf-8', 'replace'), err.decode('utf-8', 'replace')
Verify that "gdb" was built with the embedded python support enabled:
-cmd = "--eval-command=python import sys; print sys.version_info" -p = subprocess.Popen(["gdb", "--batch", cmd],
stdout=subprocess.PIPE)[](#l1.41)
-gdbpy_version, _ = p.communicate() -if gdbpy_version == b'': +gdbpy_version, _ = run_gdb("--eval-command=python import sys; print sys.version_info") +if not gdbpy_version: raise unittest.SkipTest("gdb not built with embedded python support") -# Verify that "gdb" can load our custom hooks -p = subprocess.Popen(["gdb", "--batch", cmd,
"--args", sys.executable],[](#l1.50)
stdout=subprocess.PIPE, stderr=subprocess.PIPE)[](#l1.51)
-__, gdbpy_errors = p.communicate() -if b"auto-loading has been declined" in gdbpy_errors:
- msg = "gdb security settings prevent use of custom hooks: %s"
- raise unittest.SkipTest(msg % gdbpy_errors)
+# Verify that "gdb" can load our custom hooks. In theory this should never +# fail, but we don't handle the case of the hooks file not existing if the +# tests are run from an installed Python (we'll produce failures in that case). +cmd = ['--args', sys.executable] +_, gdbpy_errors = run_gdb('--args', sys.executable) +if "auto-loading has been declined" in gdbpy_errors:
- msg = "gdb security settings prevent use of custom hooks: "
- raise unittest.SkipTest(msg + gdbpy_errors.rstrip())
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)[](#l1.69)
- stdout, _ = p.communicate()
- m = re.match(br'.[(.)].*', stdout)
- stdout, _ = run_gdb("--eval-command=python print(dir(gdb.Frame))")
- m = re.match(r'.[(.)].*', stdout) if not m: raise unittest.SkipTest("Unable to parse output from gdb.Frame.select test")
HAS_PYUP_PYDOWN = gdb_has_frame_select() @@ -61,21 +79,6 @@ class DebuggerTests(unittest.TestCase): """Test that the debugger can debug Python."""
Returns its stdout, stderr[](#l1.90)
"""[](#l1.91)
if env_vars:[](#l1.92)
env = os.environ.copy()[](#l1.93)
env.update(env_vars)[](#l1.94)
else:[](#l1.95)
env = None[](#l1.96)
out, err = subprocess.Popen([](#l1.97)
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env,[](#l1.98)
).communicate()[](#l1.99)
return out.decode('utf-8', 'replace'), err.decode('utf-8', 'replace')[](#l1.100)
- def get_stack_trace(self, source=None, script=None, breakpoint=BREAKPOINT_FN, cmds_after_breakpoint=None, @@ -132,7 +135,7 @@ class DebuggerTests(unittest.TestCase): # print ' '.join(args) # Use "args" to invoke gdb, capturing stdout, stderr:
out, err = self.run_gdb(*args, PYTHONHASHSEED='0')[](#l1.109)
out, err = run_gdb(*args, PYTHONHASHSEED='0')[](#l1.110)
# Ignore some noise on stderr due to the pending breakpoint: err = err.replace('Function "%s" not defined.\n' % breakpoint, '') @@ -149,6 +152,11 @@ class DebuggerTests(unittest.TestCase): 'Do you need "set solib-search-path" or ' '"set sysroot"?\n', '')
err = err.replace('warning: Could not load shared library symbols for '[](#l1.118)
'linux-gate.so.1.\n'[](#l1.119)
'Do you need "set solib-search-path" or '[](#l1.120)
'"set sysroot"?\n',[](#l1.121)
'')[](#l1.122)
# Ensure no unexpected error messages: self.assertEqual(err, '')