summaryrefslogtreecommitdiffstats
path: root/content/shell/tools
diff options
context:
space:
mode:
authorjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-23 08:02:23 +0000
committerjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-23 08:02:23 +0000
commit4e4b23ebae9274511fa3fad438b198c19b38c98d (patch)
tree8fc375bf11c7609692f711177dab03303c67187b /content/shell/tools
parenteb71ab6713a9d4e3b172ab77f02ce61339dc5eb8 (diff)
downloadchromium_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-xcontent/shell/tools/breakpad_integration_test.py147
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())