1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env vpython3 2*6777b538SAndroid Build Coastguard Worker# 3*6777b538SAndroid Build Coastguard Worker# Copyright 2016 The Chromium Authors 4*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 5*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file. 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Workerimport argparse 9*6777b538SAndroid Build Coastguard Workerimport os 10*6777b538SAndroid Build Coastguard Workerimport re 11*6777b538SAndroid Build Coastguard Workerimport sys 12*6777b538SAndroid Build Coastguard Workerimport tempfile 13*6777b538SAndroid Build Coastguard Worker 14*6777b538SAndroid Build Coastguard Workerif __name__ == '__main__': 15*6777b538SAndroid Build Coastguard Worker sys.path.append(os.path.join(os.path.dirname(__file__), '..')) 16*6777b538SAndroid Build Coastguard Workerfrom pylib.constants import host_paths 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Workerif host_paths.DEVIL_PATH not in sys.path: 19*6777b538SAndroid Build Coastguard Worker sys.path.append(host_paths.DEVIL_PATH) 20*6777b538SAndroid Build Coastguard Workerfrom devil.utils import cmd_helper 21*6777b538SAndroid Build Coastguard Worker 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker_MICRODUMP_BEGIN = re.compile( 24*6777b538SAndroid Build Coastguard Worker '.*google-breakpad: -----BEGIN BREAKPAD MICRODUMP-----') 25*6777b538SAndroid Build Coastguard Worker_MICRODUMP_END = re.compile( 26*6777b538SAndroid Build Coastguard Worker '.*google-breakpad: -----END BREAKPAD MICRODUMP-----') 27*6777b538SAndroid Build Coastguard Worker 28*6777b538SAndroid Build Coastguard Worker""" Example Microdump 29*6777b538SAndroid Build Coastguard Worker<timestamp> 6270 6131 F google-breakpad: -----BEGIN BREAKPAD MICRODUMP----- 30*6777b538SAndroid Build Coastguard Worker<timestamp> 6270 6131 F google-breakpad: V Chrome_Android:54.0.2790.0 31*6777b538SAndroid Build Coastguard Worker... 32*6777b538SAndroid Build Coastguard Worker<timestamp> 6270 6131 F google-breakpad: -----END BREAKPAD MICRODUMP----- 33*6777b538SAndroid Build Coastguard Worker 34*6777b538SAndroid Build Coastguard Worker""" 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard Worker 37*6777b538SAndroid Build Coastguard Workerdef GetMicroDumps(dump_path): 38*6777b538SAndroid Build Coastguard Worker """Returns all microdumps found in given log file 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard Worker Args: 41*6777b538SAndroid Build Coastguard Worker dump_path: Path to the log file. 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard Worker Returns: 44*6777b538SAndroid Build Coastguard Worker List of all microdumps as lists of lines. 45*6777b538SAndroid Build Coastguard Worker """ 46*6777b538SAndroid Build Coastguard Worker with open(dump_path, 'r') as d: 47*6777b538SAndroid Build Coastguard Worker data = d.read() 48*6777b538SAndroid Build Coastguard Worker all_dumps = [] 49*6777b538SAndroid Build Coastguard Worker current_dump = None 50*6777b538SAndroid Build Coastguard Worker for line in data.splitlines(): 51*6777b538SAndroid Build Coastguard Worker if current_dump is not None: 52*6777b538SAndroid Build Coastguard Worker if _MICRODUMP_END.match(line): 53*6777b538SAndroid Build Coastguard Worker current_dump.append(line) 54*6777b538SAndroid Build Coastguard Worker all_dumps.append(current_dump) 55*6777b538SAndroid Build Coastguard Worker current_dump = None 56*6777b538SAndroid Build Coastguard Worker else: 57*6777b538SAndroid Build Coastguard Worker current_dump.append(line) 58*6777b538SAndroid Build Coastguard Worker elif _MICRODUMP_BEGIN.match(line): 59*6777b538SAndroid Build Coastguard Worker current_dump = [] 60*6777b538SAndroid Build Coastguard Worker current_dump.append(line) 61*6777b538SAndroid Build Coastguard Worker return all_dumps 62*6777b538SAndroid Build Coastguard Worker 63*6777b538SAndroid Build Coastguard Worker 64*6777b538SAndroid Build Coastguard Workerdef SymbolizeMicroDump(stackwalker_binary_path, dump, symbols_path): 65*6777b538SAndroid Build Coastguard Worker """Runs stackwalker on microdump. 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Worker Runs the stackwalker binary at stackwalker_binary_path on a given microdump 68*6777b538SAndroid Build Coastguard Worker using the symbols at symbols_path. 69*6777b538SAndroid Build Coastguard Worker 70*6777b538SAndroid Build Coastguard Worker Args: 71*6777b538SAndroid Build Coastguard Worker stackwalker_binary_path: Path to the stackwalker binary. 72*6777b538SAndroid Build Coastguard Worker dump: The microdump to run the stackwalker on. 73*6777b538SAndroid Build Coastguard Worker symbols_path: Path the the symbols file to use. 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker Returns: 76*6777b538SAndroid Build Coastguard Worker Output from stackwalker tool. 77*6777b538SAndroid Build Coastguard Worker """ 78*6777b538SAndroid Build Coastguard Worker with tempfile.NamedTemporaryFile() as tf: 79*6777b538SAndroid Build Coastguard Worker for l in dump: 80*6777b538SAndroid Build Coastguard Worker tf.write('%s\n' % l) 81*6777b538SAndroid Build Coastguard Worker cmd = [stackwalker_binary_path, tf.name, symbols_path] 82*6777b538SAndroid Build Coastguard Worker return cmd_helper.GetCmdOutput(cmd) 83*6777b538SAndroid Build Coastguard Worker 84*6777b538SAndroid Build Coastguard Worker 85*6777b538SAndroid Build Coastguard Workerdef AddArguments(parser): 86*6777b538SAndroid Build Coastguard Worker parser.add_argument('--stackwalker-binary-path', required=True, 87*6777b538SAndroid Build Coastguard Worker help='Path to stackwalker binary.') 88*6777b538SAndroid Build Coastguard Worker parser.add_argument('--stack-trace-path', required=True, 89*6777b538SAndroid Build Coastguard Worker help='Path to stacktrace containing microdump.') 90*6777b538SAndroid Build Coastguard Worker parser.add_argument('--symbols-path', required=True, 91*6777b538SAndroid Build Coastguard Worker help='Path to symbols file.') 92*6777b538SAndroid Build Coastguard Worker parser.add_argument('--output-file', 93*6777b538SAndroid Build Coastguard Worker help='Path to dump stacktrace output to') 94*6777b538SAndroid Build Coastguard Worker 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Workerdef _PrintAndLog(line, fp): 97*6777b538SAndroid Build Coastguard Worker if fp: 98*6777b538SAndroid Build Coastguard Worker fp.write('%s\n' % line) 99*6777b538SAndroid Build Coastguard Worker print(line) 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Worker 102*6777b538SAndroid Build Coastguard Workerdef main(): 103*6777b538SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 104*6777b538SAndroid Build Coastguard Worker AddArguments(parser) 105*6777b538SAndroid Build Coastguard Worker args = parser.parse_args() 106*6777b538SAndroid Build Coastguard Worker 107*6777b538SAndroid Build Coastguard Worker micro_dumps = GetMicroDumps(args.stack_trace_path) 108*6777b538SAndroid Build Coastguard Worker if not micro_dumps: 109*6777b538SAndroid Build Coastguard Worker print('No microdump found. Exiting.') 110*6777b538SAndroid Build Coastguard Worker return 0 111*6777b538SAndroid Build Coastguard Worker 112*6777b538SAndroid Build Coastguard Worker symbolized_dumps = [] 113*6777b538SAndroid Build Coastguard Worker for micro_dump in micro_dumps: 114*6777b538SAndroid Build Coastguard Worker symbolized_dumps.append(SymbolizeMicroDump( 115*6777b538SAndroid Build Coastguard Worker args.stackwalker_binary_path, micro_dump, args.symbols_path)) 116*6777b538SAndroid Build Coastguard Worker 117*6777b538SAndroid Build Coastguard Worker try: 118*6777b538SAndroid Build Coastguard Worker fp = open(args.output_file, 'w') if args.output_file else None 119*6777b538SAndroid Build Coastguard Worker _PrintAndLog('%d microdumps found.' % len(micro_dumps), fp) 120*6777b538SAndroid Build Coastguard Worker _PrintAndLog('---------- Start output from stackwalker ----------', fp) 121*6777b538SAndroid Build Coastguard Worker for index, symbolized_dump in list(enumerate(symbolized_dumps)): 122*6777b538SAndroid Build Coastguard Worker _PrintAndLog( 123*6777b538SAndroid Build Coastguard Worker '------------------ Start dump %d ------------------' % index, fp) 124*6777b538SAndroid Build Coastguard Worker _PrintAndLog(symbolized_dump, fp) 125*6777b538SAndroid Build Coastguard Worker _PrintAndLog( 126*6777b538SAndroid Build Coastguard Worker '------------------- End dump %d -------------------' % index, fp) 127*6777b538SAndroid Build Coastguard Worker _PrintAndLog('----------- End output from stackwalker -----------', fp) 128*6777b538SAndroid Build Coastguard Worker except Exception: 129*6777b538SAndroid Build Coastguard Worker if fp: 130*6777b538SAndroid Build Coastguard Worker fp.close() 131*6777b538SAndroid Build Coastguard Worker raise 132*6777b538SAndroid Build Coastguard Worker return 0 133*6777b538SAndroid Build Coastguard Worker 134*6777b538SAndroid Build Coastguard Worker 135*6777b538SAndroid Build Coastguard Workerif __name__ == '__main__': 136*6777b538SAndroid Build Coastguard Worker sys.exit(main()) 137