3 # Copyright 2014 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
7 """Integration test for breakpad in content shell.
9 This test checks that content shell and breakpad are correctly hooked up, as
10 well as that the tools can symbolize a stack trace."""
26 parser
= optparse
.OptionParser()
27 parser
.add_option('', '--build-dir', default
='',
28 help='The build output directory.')
29 parser
.add_option('', '--binary', default
='',
30 help='The path of the binary to generate symbols for.')
31 parser
.add_option('', '--no-symbols', default
=False, action
='store_true',
32 help='Symbols are not expected to work.')
33 parser
.add_option('-j', '--jobs', default
=CONCURRENT_TASKS
, action
='store',
34 type='int', help='Number of parallel tasks to run.')
35 parser
.add_option('-v', '--verbose', action
='store_true',
36 help='Print verbose status output.')
38 (options
, _
) = parser
.parse_args()
40 if not options
.build_dir
:
41 print "Required option --build-dir missing."
44 if not options
.binary
:
45 print "Required option --binary missing."
48 if not os
.access(options
.binary
, os
.X_OK
):
49 print "Cannot find %s." % options
.binary
54 # Create a temporary directory to store the crash dumps and symbols in.
55 crash_dir
= tempfile
.mkdtemp()
58 print "# Generate symbols."
59 breakpad_tools_dir
= os
.path
.join(
60 os
.path
.dirname(__file__
), '..', '..', '..',
61 'components', 'crash', 'tools')
62 generate_symbols
= os
.path
.join(
63 breakpad_tools_dir
, 'generate_breakpad_symbols.py')
64 symbols_dir
= os
.path
.join(crash_dir
, 'symbols')
65 cmd
= [generate_symbols
,
66 '--build-dir=%s' % options
.build_dir
,
67 '--binary=%s' % options
.binary
,
68 '--symbols-dir=%s' % symbols_dir
,
69 '--jobs=%d' % options
.jobs
]
71 cmd
.append('--verbose')
73 failure
= 'Failed to run generate_breakpad_symbols.py.'
74 subprocess
.check_call(cmd
)
76 print "# Run content_shell and make it crash."
77 cmd
= [options
.binary
,
80 '--enable-crash-reporter',
81 '--crash-dumps-dir=%s' % crash_dir
]
84 failure
= 'Failed to run content_shell.'
86 subprocess
.check_call(cmd
)
88 with
open(os
.devnull
, 'w') as devnull
:
89 subprocess
.check_call(cmd
, stdout
=devnull
, stderr
=devnull
)
91 print "# Retrieve crash dump."
92 dmp_files
= glob
.glob(os
.path
.join(crash_dir
, '*.dmp'))
93 failure
= 'Expected 1 crash dump, found %d.' % len(dmp_files
)
94 if len(dmp_files
) != 1:
95 raise Exception(failure
)
96 dmp_file
= dmp_files
[0]
97 minidump
= os
.path
.join(crash_dir
, 'minidump')
99 dmp_to_minidump
= os
.path
.join(breakpad_tools_dir
, 'dmp2minidump.py')
100 cmd
= [dmp_to_minidump
, dmp_file
, minidump
]
103 failure
= 'Failed to run dmp_to_minidump.'
104 subprocess
.check_call(cmd
)
106 print "# Symbolize crash dump."
107 minidump_stackwalk
= os
.path
.join(options
.build_dir
, 'minidump_stackwalk')
108 cmd
= [minidump_stackwalk
, minidump
, symbols_dir
]
111 failure
= 'Failed to run minidump_stackwalk.'
112 proc
= subprocess
.Popen(cmd
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
)
113 stack
= proc
.communicate()[0]
115 # Check whether the stack contains a CrashIntentionally symbol.
116 found_symbol
= 'CrashIntentionally' in stack
118 if options
.no_symbols
:
122 failure
= 'Found unexpected reference to CrashIntentionally in stack'
123 raise Exception(failure
)
128 failure
= 'Could not find reference to CrashIntentionally in stack.'
129 raise Exception(failure
)
132 print "FAIL: %s" % failure
136 print "PASS: Breakpad integration test ran successfully."
141 shutil
.rmtree(crash_dir
)
143 print 'Failed to delete temp directory "%s".' % crash_dir
146 if '__main__' == __name__
: