1342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#!/usr/bin/env python 2342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# 3342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# Copyright 2013 The Chromium Authors. All rights reserved. 4342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# Use of this source code is governed by a BSD-style license that can be 5342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# found in the LICENSE file. 6342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# 7342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# Find the most recent tombstone file(s) on all connected devices 8342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# and prints their stacks. 9342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# 10342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# Assumes tombstone file was created with current symbols. 11342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 12342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport datetime 13342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport logging 14342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport multiprocessing 15342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport os 16342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport re 17342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport subprocess 18342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport sys 19342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport optparse 20342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 21342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport devil_chromium 22342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 23342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochfrom devil.android import device_blacklist 24342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochfrom devil.android import device_errors 25342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochfrom devil.android import device_utils 26342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochfrom devil.utils import run_tests_helper 27342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochfrom pylib import constants 28342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 29342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch_TZ_UTC = {'TZ': 'UTC'} 30342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 31342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochdef _ListTombstones(device): 32342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """List the tombstone files on the device. 33342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 34342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Args: 35342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch device: An instance of DeviceUtils. 36342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 37342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Yields: 38342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Tuples of (tombstone filename, date time of file on device). 39342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """ 40342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch try: 41342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if not device.PathExists('/data/tombstones', as_root=True): 42342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return 43342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # TODO(perezju): Introduce a DeviceUtils.Ls() method (crbug.com/552376). 44342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch lines = device.RunShellCommand( 45342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ['ls', '-a', '-l', '/data/tombstones'], 46342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch as_root=True, check_return=True, env=_TZ_UTC) 47342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for line in lines: 48342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if 'tombstone' in line: 49342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch details = line.split() 50342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch t = datetime.datetime.strptime(details[-3] + ' ' + details[-2], 51342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch '%Y-%m-%d %H:%M') 52342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch yield details[-1], t 53342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch except device_errors.CommandFailedError: 54342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch logging.exception('Could not retrieve tombstones.') 55342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch except device_errors.CommandTimeoutError: 56342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch logging.exception('Timed out retrieving tombstones.') 57342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 58342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 59342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochdef _GetDeviceDateTime(device): 60342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """Determine the date time on the device. 61342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 62342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Args: 63342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch device: An instance of DeviceUtils. 64342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 65342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Returns: 66342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch A datetime instance. 67342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """ 68342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch device_now_string = device.RunShellCommand( 69342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ['date'], check_return=True, env=_TZ_UTC) 70342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return datetime.datetime.strptime( 71342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch device_now_string[0], '%a %b %d %H:%M:%S %Z %Y') 72342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 73342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 74342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochdef _GetTombstoneData(device, tombstone_file): 75342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """Retrieve the tombstone data from the device 76342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 77342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Args: 78342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch device: An instance of DeviceUtils. 79342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch tombstone_file: the tombstone to retrieve 80342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 81342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Returns: 82342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch A list of lines 83342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """ 84342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return device.ReadFile( 85342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch '/data/tombstones/' + tombstone_file, as_root=True).splitlines() 86342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 87342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 88342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochdef _EraseTombstone(device, tombstone_file): 89342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """Deletes a tombstone from the device. 90342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 91342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Args: 92342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch device: An instance of DeviceUtils. 93342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch tombstone_file: the tombstone to delete. 94342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """ 95342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return device.RunShellCommand( 96342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ['rm', '/data/tombstones/' + tombstone_file], 97342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch as_root=True, check_return=True) 98342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 99342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 100342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochdef _DeviceAbiToArch(device_abi): 101342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # The order of this list is significant to find the more specific match (e.g., 102342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # arm64) before the less specific (e.g., arm). 103342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch arches = ['arm64', 'arm', 'x86_64', 'x86_64', 'x86', 'mips'] 104342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for arch in arches: 105342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if arch in device_abi: 106342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return arch 107342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch raise RuntimeError('Unknown device ABI: %s' % device_abi) 108342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 109342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochdef _ResolveSymbols(tombstone_data, include_stack, device_abi): 110342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """Run the stack tool for given tombstone input. 111342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 112342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Args: 113342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch tombstone_data: a list of strings of tombstone data. 114342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch include_stack: boolean whether to include stack data in output. 115342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch device_abi: the default ABI of the device which generated the tombstone. 116342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 117342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Yields: 118342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch A string for each line of resolved stack output. 119342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """ 120342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # Check if the tombstone data has an ABI listed, if so use this in preference 121342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # to the device's default ABI. 122342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for line in tombstone_data: 123342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch found_abi = re.search('ABI: \'(.+?)\'', line) 124342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if found_abi: 125342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch device_abi = found_abi.group(1) 126342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch arch = _DeviceAbiToArch(device_abi) 127342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if not arch: 128342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return 129342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 130342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch stack_tool = os.path.join(os.path.dirname(__file__), '..', '..', 131342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 'third_party', 'android_platform', 'development', 132342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 'scripts', 'stack') 133342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch cmd = [stack_tool, '--arch', arch, '--output-directory', 134342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch constants.GetOutDirectory()] 135342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) 136342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch output = proc.communicate(input='\n'.join(tombstone_data))[0] 137342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for line in output.split('\n'): 138342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if not include_stack and 'Stack Data:' in line: 139342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch break 140342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch yield line 141342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 142342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 143342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochdef _ResolveTombstone(tombstone): 144342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch lines = [] 145342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch lines += [tombstone['file'] + ' created on ' + str(tombstone['time']) + 146342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ', about this long ago: ' + 147342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch (str(tombstone['device_now'] - tombstone['time']) + 148342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ' Device: ' + tombstone['serial'])] 149342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch logging.info('\n'.join(lines)) 150342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch logging.info('Resolving...') 151342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch lines += _ResolveSymbols(tombstone['data'], tombstone['stack'], 152342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch tombstone['device_abi']) 153342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return lines 154342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 155342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 156342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochdef _ResolveTombstones(jobs, tombstones): 157342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """Resolve a list of tombstones. 158342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 159342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Args: 160342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch jobs: the number of jobs to use with multiprocess. 161342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch tombstones: a list of tombstones. 162342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """ 163342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if not tombstones: 164342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch logging.warning('No tombstones to resolve.') 165342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return 166342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if len(tombstones) == 1: 167342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch data = [_ResolveTombstone(tombstones[0])] 168342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch else: 169342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch pool = multiprocessing.Pool(processes=jobs) 170342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch data = pool.map(_ResolveTombstone, tombstones) 171342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for tombstone in data: 172342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for line in tombstone: 173342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch logging.info(line) 174342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 175342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 176342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochdef _GetTombstonesForDevice(device, options): 177342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """Returns a list of tombstones on a given device. 178342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 179342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Args: 180342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch device: An instance of DeviceUtils. 181342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch options: command line arguments from OptParse 182342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch """ 183342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ret = [] 184342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch all_tombstones = list(_ListTombstones(device)) 185342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if not all_tombstones: 186342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch logging.warning('No tombstones.') 187342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return ret 188342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 189342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # Sort the tombstones in date order, descending 190342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch all_tombstones.sort(cmp=lambda a, b: cmp(b[1], a[1])) 191342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 192342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # Only resolve the most recent unless --all-tombstones given. 193342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch tombstones = all_tombstones if options.all_tombstones else [all_tombstones[0]] 194342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 195342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch device_now = _GetDeviceDateTime(device) 196342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch try: 197342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for tombstone_file, tombstone_time in tombstones: 198342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ret += [{'serial': str(device), 199342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 'device_abi': device.product_cpu_abi, 200342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 'device_now': device_now, 201342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 'time': tombstone_time, 202342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 'file': tombstone_file, 203342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 'stack': options.stack, 204342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 'data': _GetTombstoneData(device, tombstone_file)}] 205342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch except device_errors.CommandFailedError: 206342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for line in device.RunShellCommand( 207342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ['ls', '-a', '-l', '/data/tombstones'], 208342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch as_root=True, check_return=True, env=_TZ_UTC, timeout=60): 209342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch logging.info('%s: %s', str(device), line) 210342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch raise 211342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 212342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # Erase all the tombstones if desired. 213342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if options.wipe_tombstones: 214342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for tombstone_file, _ in all_tombstones: 215342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch _EraseTombstone(device, tombstone_file) 216342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 217342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return ret 218342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 219342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 220342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochdef main(): 221342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch custom_handler = logging.StreamHandler(sys.stdout) 222342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch custom_handler.setFormatter(run_tests_helper.CustomFormatter()) 223342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch logging.getLogger().addHandler(custom_handler) 224342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch logging.getLogger().setLevel(logging.INFO) 225342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 226342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch parser = optparse.OptionParser() 227342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch parser.add_option('--device', 228342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch help='The serial number of the device. If not specified ' 229342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 'will use all devices.') 230342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch parser.add_option('--blacklist-file', help='Device blacklist JSON file.') 231342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch parser.add_option('-a', '--all-tombstones', action='store_true', 232342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch help="""Resolve symbols for all tombstones, rather than just 233342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch the most recent""") 234342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch parser.add_option('-s', '--stack', action='store_true', 235342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch help='Also include symbols for stack data') 236342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch parser.add_option('-w', '--wipe-tombstones', action='store_true', 237342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch help='Erase all tombstones from device after processing') 238342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch parser.add_option('-j', '--jobs', type='int', 239342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch default=4, 240342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch help='Number of jobs to use when processing multiple ' 241342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 'crash stacks.') 242342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch parser.add_option('--output-directory', 243342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch help='Path to the root build directory.') 244342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch options, _ = parser.parse_args() 245342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 246342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch devil_chromium.Initialize() 247342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 248342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch blacklist = (device_blacklist.Blacklist(options.blacklist_file) 249342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if options.blacklist_file 250342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch else None) 251342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 252342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if options.output_directory: 253342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch constants.SetOutputDirectory(options.output_directory) 254342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # Do an up-front test that the output directory is known. 255342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch constants.CheckOutputDirectory() 256342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 257342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if options.device: 258342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch devices = [device_utils.DeviceUtils(options.device)] 259342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch else: 260342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch devices = device_utils.DeviceUtils.HealthyDevices(blacklist) 261342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 262342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # This must be done serially because strptime can hit a race condition if 263342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # used for the first time in a multithreaded environment. 264342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch # http://bugs.python.org/issue7980 265342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch tombstones = [] 266342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for device in devices: 267342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch tombstones += _GetTombstonesForDevice(device, options) 268342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 269342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch _ResolveTombstones(options.jobs, tombstones) 270342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 271342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 272342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochif __name__ == '__main__': 273342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch sys.exit(main()) 274