diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-23 08:02:23 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-23 08:02:23 +0000 |
commit | 4e4b23ebae9274511fa3fad438b198c19b38c98d (patch) | |
tree | 8fc375bf11c7609692f711177dab03303c67187b /content/shell/tools | |
parent | eb71ab6713a9d4e3b172ab77f02ce61339dc5eb8 (diff) | |
download | chromium_src-4e4b23ebae9274511fa3fad438b198c19b38c98d.zip chromium_src-4e4b23ebae9274511fa3fad438b198c19b38c98d.tar.gz chromium_src-4e4b23ebae9274511fa3fad438b198c19b38c98d.tar.bz2 |
Add a breakpad / content_shell integration test
The test is supposed to ensure that the breakpad component is correctly
hooked up to content_shell, and that the surrounding tools can actually
convert a crash into a symbolized stack dump.
This version is currently Linux-only, other platforms will be added.
The test is based on
http://www.chromium.org/developers/testing/webkit-layout-tests/using-breakpad-with-content-shell
This would have caught e.g. a call to base::GetLinuxDistro() being added
on the UI thread, or dump_syms not supporting debug fission yet.
The test needs to be executed like this:
$ content/shell/tools/breakpad_integration_test.py \
--build-dir=out/Debug --binary=out/Debug/content_shell
# Generate symbols.
# Run content_shell and make it crash.
# Retrieve crash dump.
# Symbolize crash dump.
PASS: Breakpad integration test ran successfully.
BUG=372928
R=thestig@chromium.org, rsesek@chromium.org
Review URL: https://codereview.chromium.org/293993017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272444 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/shell/tools')
-rwxr-xr-x | content/shell/tools/breakpad_integration_test.py | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/content/shell/tools/breakpad_integration_test.py b/content/shell/tools/breakpad_integration_test.py new file mode 100755 index 0000000..c9742fe --- /dev/null +++ b/content/shell/tools/breakpad_integration_test.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python +# +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Integration test for breakpad in content shell. + +This test checks that content shell and breakpad are correctly hooked up, as +well as that the tools can symbolize a stack trace.""" + + +import glob +import optparse +import os +import shutil +import subprocess +import sys +import tempfile + + +CONCURRENT_TASKS=4 + + +def main(): + parser = optparse.OptionParser() + parser.add_option('', '--build-dir', default='', + help='The build output directory.') + parser.add_option('', '--binary', default='', + help='The path of the binary to generate symbols for.') + parser.add_option('', '--no-symbols', default=False, action='store_true', + help='Symbols are not expected to work.') + parser.add_option('-j', '--jobs', default=CONCURRENT_TASKS, action='store', + type='int', help='Number of parallel tasks to run.') + parser.add_option('-v', '--verbose', action='store_true', + help='Print verbose status output.') + + (options, _) = parser.parse_args() + + if not options.build_dir: + print "Required option --build-dir missing." + return 1 + + if not options.binary: + print "Required option --binary missing." + return 1 + + if not os.access(options.binary, os.X_OK): + print "Cannot find %s." % options.binary + return 1 + + failure = '' + + # Create a temporary directory to store the crash dumps and symbols in. + crash_dir = tempfile.mkdtemp() + + try: + print "# Generate symbols." + breakpad_tools_dir = os.path.join( + os.path.dirname(__file__), '..', '..', '..', + 'components', 'breakpad', 'tools') + generate_symbols = os.path.join( + breakpad_tools_dir, 'generate_breakpad_symbols.py') + symbols_dir = os.path.join(crash_dir, 'symbols') + cmd = [generate_symbols, + '--build-dir=%s' % options.build_dir, + '--binary=%s' % options.binary, + '--symbols-dir=%s' % symbols_dir, + '--jobs=%d' % options.jobs] + if options.verbose: + cmd.append('--verbose') + print ' '.join(cmd) + failure = 'Failed to run generate_breakpad_symbols.py.' + subprocess.check_call(cmd) + + print "# Run content_shell and make it crash." + cmd = [options.binary, + '--dump-render-tree', + 'chrome://crash', + '--enable-crash-reporter', + '--crash-dumps-dir=%s' % crash_dir] + if options.verbose: + print ' '.join(cmd) + failure = 'Failed to run content_shell.' + if options.verbose: + subprocess.check_call(cmd) + else: + with open(os.devnull, 'w') as devnull: + subprocess.check_call(cmd, stdout=devnull, stderr=devnull) + + print "# Retrieve crash dump." + dmp_files = glob.glob(os.path.join(crash_dir, '*.dmp')) + failure = 'Expected 1 crash dump, found %d.' % len(dmp_files) + if len(dmp_files) != 1: + raise Exception(failure) + dmp_file = dmp_files[0] + minidump = os.path.join(crash_dir, 'minidump') + + dmp_to_minidump = os.path.join(breakpad_tools_dir, 'dmp2minidump.py') + cmd = [dmp_to_minidump, dmp_file, minidump] + if options.verbose: + print ' '.join(cmd) + failure = 'Failed to run dmp_to_minidump.' + subprocess.check_call(cmd) + + print "# Symbolize crash dump." + minidump_stackwalk = os.path.join(options.build_dir, 'minidump_stackwalk') + cmd = [minidump_stackwalk, minidump, symbols_dir] + if options.verbose: + print ' '.join(cmd) + failure = 'Failed to run minidump_stackwalk.' + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stack = proc.communicate()[0] + + # Check whether the stack contains a CrashIntentionally symbol. + found_symbol = 'CrashIntentionally' in stack + + if options.no_symbols: + if found_symbol: + if options.verbose: + print stack + failure = 'Found unexpected reference to CrashIntentionally in stack' + raise Exception(failure) + else: + if not found_symbol: + if options.verbose: + print stack + failure = 'Could not find reference to CrashIntentionally in stack.' + raise Exception(failure) + + except: + print "FAIL: %s" % failure + return 1 + + else: + print "PASS: Breakpad integration test ran successfully." + return 0 + + finally: + try: + shutil.rmtree(crash_dir) + except: + print 'Failed to delete temp directory "%s".' % crash_dir + + +if '__main__' == __name__: + sys.exit(main()) |