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