diff options
author | R David Murray <rdmurray@bitdance.com> | 2012-10-27 17:47:49 (GMT) |
---|---|---|
committer | R David Murray <rdmurray@bitdance.com> | 2012-10-27 17:47:49 (GMT) |
commit | 3e66f0d14d4541f85ee5daf00dbd3150a02fa4aa (patch) | |
tree | fc19e6e9a052d0adaf9d4c93a776668424e0a9db /Lib | |
parent | f8d370e30dde8ed17834f6eac8d026c6395e7101 (diff) | |
download | cpython-3e66f0d14d4541f85ee5daf00dbd3150a02fa4aa.zip cpython-3e66f0d14d4541f85ee5daf00dbd3150a02fa4aa.tar.gz cpython-3e66f0d14d4541f85ee5daf00dbd3150a02fa4aa.tar.bz2 |
#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.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_gdb.py | 77 |
1 files changed, 42 insertions, 35 deletions
diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 3bf718aa..9d8ff8e 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -19,27 +19,47 @@ 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(r"^GNU gdb [^\d]*(\d+)\.", gdb_version) -if int(gdb_version_number.group(1)) < 7: +gdb_version_number = re.search("^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) +# Location of custom hooks file in a repository checkout. +checkout_hook_path = os.path.join(os.path.dirname(sys.executable), + 'python-gdb.py') + +def run_gdb(*args, **env_vars): + """Runs gdb in --batch mode with the additional arguments given by *args. + + Returns its (stdout, stderr) + """ + if env_vars: + env = os.environ.copy() + env.update(env_vars) + else: + env = None + base_cmd = ('gdb', '--batch') + if (gdb_major_version, gdb_minor_version) >= (7, 4): + base_cmd += ('-iex', 'add-auto-load-safe-path ' + checkout_hook_path) + out, err = subprocess.Popen(base_cmd + args, + stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, + ).communicate() + return out, err + # 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) -gdbpy_version, _ = p.communicate() -if gdbpy_version == '': +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], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) -__, 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: " def python_is_optimized(): cflags = sysconfig.get_config_vars()['PY_CFLAGS'] @@ -51,10 +71,7 @@ def python_is_optimized(): 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() + 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") @@ -67,21 +84,6 @@ class DebuggerTests(unittest.TestCase): """Test that the debugger can debug Python.""" - def run_gdb(self, *args, **env_vars): - """Runs gdb with the command line given by *args. - - Returns its stdout, stderr - """ - if env_vars: - env = os.environ.copy() - env.update(env_vars) - else: - env = None - out, err = subprocess.Popen( - args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env - ).communicate() - return out, err - def get_stack_trace(self, source=None, script=None, breakpoint='PyObject_Print', cmds_after_breakpoint=None, @@ -138,7 +140,7 @@ class DebuggerTests(unittest.TestCase): # print ' '.join(args) # Use "args" to invoke gdb, capturing stdout, stderr: - out, err = self.run_gdb(*args, PYTHONHASHSEED='0') + out, err = run_gdb(*args, PYTHONHASHSEED='0') # Ignore some noise on stderr due to the pending breakpoint: err = err.replace('Function "%s" not defined.\n' % breakpoint, '') @@ -155,6 +157,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 ' + 'linux-gate.so.1.\n' + 'Do you need "set solib-search-path" or ' + '"set sysroot"?\n', + '') # Ensure no unexpected error messages: self.assertEqual(err, '') |