Index: ppapi/native_client/tests/breakpad_crash_test/crash_dump_tester.py |
diff --git a/ppapi/native_client/tests/breakpad_crash_test/crash_dump_tester.py b/ppapi/native_client/tests/breakpad_crash_test/crash_dump_tester.py |
index 4f79fbfd3bbc8ffc269c733a57270947df2ad2ee..fa7733d52ca19792b042ed901784ed8de4b1870d 100755 |
--- a/ppapi/native_client/tests/breakpad_crash_test/crash_dump_tester.py |
+++ b/ppapi/native_client/tests/breakpad_crash_test/crash_dump_tester.py |
@@ -37,45 +37,25 @@ def ReadDumpTxtFile(filename): |
return dump_info |
-def StartCrashService(browser_path, dumps_dir, windows_pipe_name, win64): |
- if sys.platform == 'win32': |
- # Find crash_service.exe relative to chrome.exe. This is a bit icky. |
- browser_dir = os.path.dirname(browser_path) |
- # Ideally we would just query the OS here to find out whether we |
- # are running x86-32 or x86-64 Windows, but Python's win32api |
- # module does not contain a wrapper for GetNativeSystemInfo(), |
- # which is what NaCl uses to check this, or for IsWow64Process(), |
- # which is what Chromium uses. Instead, we just rely on the build |
- # system to tell us. Furthermore, on an x86-64 Windows system we |
- # could launch both versions of crash_service, in order to check |
- # that they do not interfere, but for simplicity we do not. |
- if win64: |
- executable_name = 'crash_service64.exe' |
- else: |
- executable_name = 'crash_service.exe' |
- proc = subprocess.Popen([os.path.join(browser_dir, executable_name), |
- '--dumps-dir=%s' % dumps_dir, |
- '--pipe-name=%s' % windows_pipe_name]) |
- def Cleanup(): |
- # Note that if the process has already exited, this will raise |
- # an 'Access is denied' WindowsError exception, but |
- # crash_service.exe is not supposed to do this and such |
- # behaviour should make the test fail. |
- proc.terminate() |
- status = proc.wait() |
- sys.stdout.write('crash_dump_tester: ' |
- 'crash_service.exe exited with status %s\n' % status) |
- # We add a delay because there is probably a race condition: |
- # crash_service.exe might not have finished doing |
- # CreateNamedPipe() before NaCl does a crash dump and tries to |
- # connect to that pipe. |
- # TODO(mseaborn): We could change crash_service.exe to report when |
- # it has successfully created the named pipe. |
- time.sleep(1) |
- else: |
- def Cleanup(): |
- pass |
- return Cleanup |
+def StartCrashService(browser_path, dumps_dir, windows_pipe_name, |
+ cleanup_funcs, crash_service_exe): |
+ # Find crash_service.exe relative to chrome.exe. This is a bit icky. |
+ browser_dir = os.path.dirname(browser_path) |
+ proc = subprocess.Popen([os.path.join(browser_dir, crash_service_exe), |
+ '--dumps-dir=%s' % dumps_dir, |
+ '--pipe-name=%s' % windows_pipe_name]) |
+ |
+ def Cleanup(): |
+ # Note that if the process has already exited, this will raise |
+ # an 'Access is denied' WindowsError exception, but |
+ # crash_service.exe is not supposed to do this and such |
+ # behaviour should make the test fail. |
+ proc.terminate() |
+ status = proc.wait() |
+ sys.stdout.write('crash_dump_tester: %s exited with status %s\n' |
+ % (crash_service_exe, status)) |
+ |
+ cleanup_funcs.append(Cleanup) |
def GetDumpFiles(dumps_dir): |
@@ -88,16 +68,31 @@ def GetDumpFiles(dumps_dir): |
if dump_file.endswith('.dmp')] |
-def Main(): |
+def Main(cleanup_funcs): |
parser = browser_tester.BuildArgParser() |
parser.add_option('--expected_crash_dumps', dest='expected_crash_dumps', |
type=int, default=0, |
help='The number of crash dumps that we should expect') |
+ parser.add_option('--expected_process_type_for_crash', |
+ dest='expected_process_type_for_crash', |
+ type=str, default='nacl-loader', |
+ help='The type of Chromium process that we expect the ' |
+ 'crash dump to be for') |
+ # Ideally we would just query the OS here to find out whether we are |
+ # running x86-32 or x86-64 Windows, but Python's win32api module |
+ # does not contain a wrapper for GetNativeSystemInfo(), which is |
+ # what NaCl uses to check this, or for IsWow64Process(), which is |
+ # what Chromium uses. Instead, we just rely on the build system to |
+ # tell us. |
parser.add_option('--win64', dest='win64', action='store_true', |
help='Pass this if we are running tests for x86-64 Windows') |
options, args = parser.parse_args() |
dumps_dir = tempfile.mkdtemp(prefix='nacl_crash_dump_tester_') |
+ def CleanUpDumpsDir(): |
+ browsertester.browserlauncher.RemoveDirectory(dumps_dir) |
+ cleanup_funcs.append(CleanUpDumpsDir) |
+ |
# To get a guaranteed unique pipe name, use the base name of the |
# directory we just created. |
windows_pipe_name = r'\\.\pipe\%s_crash_service' % os.path.basename(dumps_dir) |
@@ -109,15 +104,26 @@ def Main(): |
# Override the default (global) Windows pipe name that Chromium will |
# use for out-of-process crash reporting. |
os.environ['CHROME_BREAKPAD_PIPE_NAME'] = windows_pipe_name |
+ # Launch the x86-32 crash service so that we can handle crashes in |
+ # the browser process. |
+ StartCrashService(options.browser_path, dumps_dir, windows_pipe_name, |
+ cleanup_funcs, 'crash_service.exe') |
+ if options.win64: |
+ # Launch the x86-64 crash service so that we can handle crashes |
+ # in the NaCl loader process (nacl64.exe). |
+ StartCrashService(options.browser_path, dumps_dir, windows_pipe_name, |
+ cleanup_funcs, 'crash_service64.exe') |
+ # We add a delay because there is probably a race condition: |
+ # crash_service.exe might not have finished doing |
+ # CreateNamedPipe() before NaCl does a crash dump and tries to |
+ # connect to that pipe. |
+ # TODO(mseaborn): We could change crash_service.exe to report when |
+ # it has successfully created the named pipe. |
+ time.sleep(1) |
elif sys.platform == 'darwin': |
os.environ['BREAKPAD_DUMP_LOCATION'] = dumps_dir |
- cleanup_func = StartCrashService(options.browser_path, dumps_dir, |
- windows_pipe_name, options.win64) |
- try: |
- result = browser_tester.Run(options.url, options) |
- finally: |
- cleanup_func() |
+ result = browser_tester.Run(options.url, options) |
dmp_files = GetDumpFiles(dumps_dir) |
failed = False |
@@ -140,9 +146,9 @@ def Main(): |
# Check that the crash dump comes from the NaCl process. |
dump_info = ReadDumpTxtFile(second_file) |
if 'ptype' in dump_info: |
- msg = ('crash_dump_tester: ERROR: Unexpected ptype value: %r\n' |
- % dump_info['ptype']) |
- if dump_info['ptype'] != 'nacl-loader': |
+ msg = ('crash_dump_tester: ERROR: Unexpected ptype value: %r != %r\n' |
+ % (dump_info['ptype'], options.expected_process_type_for_crash)) |
+ if dump_info['ptype'] != options.expected_process_type_for_crash: |
sys.stdout.write(msg) |
failed = True |
else: |
@@ -158,9 +164,17 @@ def Main(): |
else: |
sys.stdout.write('crash_dump_tester: PASSED\n') |
- browsertester.browserlauncher.RemoveDirectory(dumps_dir) |
return result |
+def MainWrapper(): |
+ cleanup_funcs = [] |
+ try: |
+ return Main(cleanup_funcs) |
+ finally: |
+ for func in cleanup_funcs: |
+ func() |
+ |
+ |
if __name__ == '__main__': |
- sys.exit(Main()) |
+ sys.exit(MainWrapper()) |