15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/python 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import subprocess 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import tempfile 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import time 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)script_dir = os.path.dirname(__file__) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sys.path.append(os.path.join(script_dir, 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '../../tools/browser_tester')) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import browser_tester 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import browsertester.browserlauncher 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This script extends browser_tester to check for the presence of 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Breakpad crash dumps. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This reads a file of lines containing 'key:value' pairs. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# The file contains entries like the following: 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# plat:Win32 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# prod:Chromium 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ptype:nacl-loader 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# rept:crash svc 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def ReadDumpTxtFile(filename): 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump_info = {} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fh = open(filename, 'r') 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in fh: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ':' in line: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key, value = line.rstrip().split(':', 1) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump_info[key] = value 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fh.close() 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dump_info 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def StartCrashService(browser_path, dumps_dir, windows_pipe_name, 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cleanup_funcs, crash_service_exe, 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) skip_if_missing=False): 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Find crash_service.exe relative to chrome.exe. This is a bit icky. 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_dir = os.path.dirname(browser_path) 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) crash_service_path = os.path.join(browser_dir, crash_service_exe) 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if skip_if_missing and not os.path.exists(crash_service_path): 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) proc = subprocess.Popen([crash_service_path, 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) '--v=1', # Verbose output for debugging failures 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) '--dumps-dir=%s' % dumps_dir, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) '--pipe-name=%s' % windows_pipe_name]) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def Cleanup(): 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Note that if the process has already exited, this will raise 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # an 'Access is denied' WindowsError exception, but 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # crash_service.exe is not supposed to do this and such 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # behaviour should make the test fail. 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proc.terminate() 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = proc.wait() 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sys.stdout.write('crash_dump_tester: %s exited with status %s\n' 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) % (crash_service_exe, status)) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cleanup_funcs.append(Cleanup) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def ListPathsInDir(dir_path): 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if os.path.exists(dir_path): 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return [os.path.join(dir_path, name) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for name in os.listdir(dir_path)] 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return [] 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def GetDumpFiles(dumps_dirs): 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) all_files = [filename 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for dumps_dir in dumps_dirs 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for filename in ListPathsInDir(dumps_dir)] 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.stdout.write('crash_dump_tester: Found %i files\n' % len(all_files)) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for dump_file in all_files: 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sys.stdout.write(' %s (size %i)\n' 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) % (dump_file, os.stat(dump_file).st_size)) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [dump_file for dump_file in all_files 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if dump_file.endswith('.dmp')] 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def Main(cleanup_funcs): 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser = browser_tester.BuildArgParser() 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.add_option('--expected_crash_dumps', dest='expected_crash_dumps', 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type=int, default=0, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) help='The number of crash dumps that we should expect') 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parser.add_option('--expected_process_type_for_crash', 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dest='expected_process_type_for_crash', 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type=str, default='nacl-loader', 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) help='The type of Chromium process that we expect the ' 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'crash dump to be for') 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Ideally we would just query the OS here to find out whether we are 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # running x86-32 or x86-64 Windows, but Python's win32api module 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # does not contain a wrapper for GetNativeSystemInfo(), which is 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # what NaCl uses to check this, or for IsWow64Process(), which is 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # what Chromium uses. Instead, we just rely on the build system to 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # tell us. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.add_option('--win64', dest='win64', action='store_true', 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) help='Pass this if we are running tests for x86-64 Windows') 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options, args = parser.parse_args() 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) temp_dir = tempfile.mkdtemp(prefix='nacl_crash_dump_tester_') 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def CleanUpTempDir(): 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browsertester.browserlauncher.RemoveDirectory(temp_dir) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cleanup_funcs.append(CleanUpTempDir) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # To get a guaranteed unique pipe name, use the base name of the 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # directory we just created. 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) windows_pipe_name = r'\\.\pipe\%s_crash_service' % os.path.basename(temp_dir) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # This environment variable enables Breakpad crash dumping in 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # non-official builds of Chromium. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os.environ['CHROME_HEADLESS'] = '1' 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sys.platform == 'win32': 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dumps_dir = temp_dir 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Override the default (global) Windows pipe name that Chromium will 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # use for out-of-process crash reporting. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os.environ['CHROME_BREAKPAD_PIPE_NAME'] = windows_pipe_name 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Launch the x86-32 crash service so that we can handle crashes in 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # the browser process. 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartCrashService(options.browser_path, dumps_dir, windows_pipe_name, 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cleanup_funcs, 'crash_service.exe') 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if options.win64: 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Launch the x86-64 crash service so that we can handle crashes 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # in the NaCl loader process (nacl64.exe). 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) # Skip if missing, since in win64 builds crash_service.exe is 64-bit 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) # and crash_service64.exe does not exist. 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartCrashService(options.browser_path, dumps_dir, windows_pipe_name, 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cleanup_funcs, 'crash_service64.exe', 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) skip_if_missing=True) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # We add a delay because there is probably a race condition: 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # crash_service.exe might not have finished doing 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # CreateNamedPipe() before NaCl does a crash dump and tries to 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # connect to that pipe. 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(mseaborn): We could change crash_service.exe to report when 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # it has successfully created the named pipe. 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) time.sleep(1) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif sys.platform == 'darwin': 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dumps_dir = temp_dir 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os.environ['BREAKPAD_DUMP_LOCATION'] = dumps_dir 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif sys.platform.startswith('linux'): 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # The "--user-data-dir" option is not effective for the Breakpad 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # setup in Linux Chromium, because Breakpad is initialized before 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # "--user-data-dir" is read. So we set HOME to redirect the crash 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # dumps to a temporary directory. 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) home_dir = temp_dir 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) os.environ['HOME'] = home_dir 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) options.enable_crash_reporter = True 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result = browser_tester.Run(options.url, options) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Find crash dump results. 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if sys.platform.startswith('linux'): 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Look in "~/.config/*/Crash Reports". This will find crash 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # reports under ~/.config/chromium or ~/.config/google-chrome, or 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # under other subdirectories in case the branding is changed. 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dumps_dirs = [os.path.join(path, 'Crash Reports') 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for path in ListPathsInDir(os.path.join(home_dir, '.config'))] 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dumps_dirs = [dumps_dir] 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dmp_files = GetDumpFiles(dumps_dirs) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = False 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg = ('crash_dump_tester: ERROR: Got %i crash dumps but expected %i\n' % 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (len(dmp_files), options.expected_crash_dumps)) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(dmp_files) != options.expected_crash_dumps: 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.stdout.write(msg) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = True 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for dump_file in dmp_files: 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Sanity check: Make sure dumping did not fail after opening the file. 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg = 'crash_dump_tester: ERROR: Dump file is empty\n' 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if os.stat(dump_file).st_size == 0: 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sys.stdout.write(msg) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) failed = True 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # On Windows, the crash dumps should come in pairs of a .dmp and 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # .txt file. 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if sys.platform == 'win32': 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) second_file = dump_file[:-4] + '.txt' 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg = ('crash_dump_tester: ERROR: File %r is missing a corresponding ' 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '%r file\n' % (dump_file, second_file)) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not os.path.exists(second_file): 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.stdout.write(msg) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = True 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Check that the crash dump comes from the NaCl process. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump_info = ReadDumpTxtFile(second_file) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if 'ptype' in dump_info: 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg = ('crash_dump_tester: ERROR: Unexpected ptype value: %r != %r\n' 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) % (dump_info['ptype'], options.expected_process_type_for_crash)) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if dump_info['ptype'] != options.expected_process_type_for_crash: 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.stdout.write(msg) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = True 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.stdout.write('crash_dump_tester: ERROR: Missing ptype field\n') 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = True 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # TODO(mseaborn): Ideally we would also check that a backtrace 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # containing an expected function name can be extracted from the 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # crash dump. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if failed: 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.stdout.write('crash_dump_tester: FAILED\n') 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = 1 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.stdout.write('crash_dump_tester: PASSED\n') 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def MainWrapper(): 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cleanup_funcs = [] 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try: 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Main(cleanup_funcs) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) finally: 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for func in cleanup_funcs: 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) func() 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__': 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sys.exit(MainWrapper()) 226