tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

stackwalker.py (3904B)


      1 #!/usr/bin/env vpython3
      2 #
      3 # Copyright 2016 The Chromium Authors
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 
      7 
      8 import argparse
      9 import os
     10 import re
     11 import sys
     12 import tempfile
     13 
     14 if __name__ == '__main__':
     15  sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
     16 from pylib.constants import host_paths
     17 
     18 if host_paths.DEVIL_PATH not in sys.path:
     19  sys.path.append(host_paths.DEVIL_PATH)
     20 from 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 
     37 def 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):
     53        current_dump.append(line)
     54        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 = []
     60      current_dump.append(line)
     61  return all_dumps
     62 
     63 
     64 def 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 
     85 def 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 
     96 def _PrintAndLog(line, fp):
     97  if fp:
     98    fp.write('%s\n' % line)
     99  print(line)
    100 
    101 
    102 def 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:
    109    print('No microdump found. Exiting.')
    110    return 0
    111 
    112  symbolized_dumps = []
    113  for micro_dump in micro_dumps:
    114    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 
    135 if __name__ == '__main__':
    136  sys.exit(main())