xref: /aosp_15_r20/external/cronet/build/android/stacktrace/stackwalker.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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