#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
This script can take an Apple-style CrashReporter log and symbolicate it. This
is useful for when a user's reports aren't being uploaded, for example.

Only versions 6, 7, 8, and 9 reports are supported. For more information on the
file format, reference this document:
  TN2123 <http://developer.apple.com/library/mac/#technotes/tn2004/tn2123.html>

Information on symbolication was gleaned from:
  <http://developer.apple.com/tools/xcode/symbolizingcrashdumps.html>
"""

import optparse
import os.path
import re
import subprocess
import sys

# Maps binary image identifiers to binary names (minus the .dSYM portion) found
# in the archive. These are the only objects that will be looked up.
SYMBOL_IMAGE_MAP = {
  'com.google.Chrome': 'Google Chrome.app',
  'com.google.Chrome.framework': 'Google Chrome Framework.framework',
  'com.google.Chrome.helper': 'Google Chrome Helper.app'
}

class CrashReport(object):
  """A parsed representation of an Apple CrashReport text file."""
  def __init__(self, file_name):
    super(CrashReport, self).__init__()
    self.report_info = {}
    self.threads = []
    self._binary_images = {}

    fd = open(file_name, 'r')
    self._ParseHeader(fd)

    # Try and get the report version. If it's not a version we handle, abort.
    self.report_version = int(self.report_info['Report Version'])
    # Version 6: 10.5 and 10.6 crash report
    # Version 7: 10.6 spindump report
    # Version 8: 10.7 spindump report
    # Version 9: 10.7 crash report
    valid_versions = (6, 7, 8, 9)
    if self.report_version not in valid_versions:
      raise Exception("Only crash reports of versions %s are accepted." %
          str(valid_versions))

    # If this is a spindump (version 7 or 8 report), use a special parser. The
    # format is undocumented, but is similar to version 6. However, the spindump
    # report contains user and kernel stacks for every process on the system.
    if self.report_version == 7 or self.report_version == 8:
      self._ParseSpindumpStack(fd)
    else:
      self._ParseStack(fd)

    self._ParseBinaryImages(fd)
    fd.close()

  def Symbolicate(self, symbol_path):
    """Symbolicates a crash report stack trace."""
    # In order to be efficient, collect all the offsets that will be passed to
    # atos by the image name.
    offsets_by_image = self._CollectAddressesForImages(SYMBOL_IMAGE_MAP.keys())

    # For each image, run atos with the list of addresses.
    for image_name, addresses in offsets_by_image.items():
      # If this image was not loaded or is in no stacks, skip.
      if image_name not in self._binary_images or not len(addresses):
        continue

      # Combine the |image_name| and |symbol_path| into the path of the dSYM.
      dsym_file = self._GetDSymPath(symbol_path, image_name)

      # From the list of 2-Tuples of (frame, address), create a list of just
      # addresses.
      address_list = map(lambda x: x[1], addresses)

      # Look up the load address of the image.
      binary_base = self._binary_images[image_name][0]

      # This returns a list of just symbols. The indices will match up with the
      # list of |addresses|.
      symbol_names = self._RunAtos(binary_base, dsym_file, address_list)
      if not symbol_names:
        print 'Error loading symbols for ' + image_name
        continue

      # Attaches a list of symbol names to stack frames. This assumes that the
      # order of |addresses| has stayed the same as |symbol_names|.
      self._AddSymbolsToFrames(symbol_names, addresses)

  def _ParseHeader(self, fd):
    """Parses the header section of a crash report, which contains the OS and
    application version information."""
    # The header is made up of different sections, depending on the type of
    # report and the report version. Almost all have a format of a key and
    # value separated by a colon. Accumulate all of these artifacts into a
    # dictionary until the first thread stack is reached.
    thread_re = re.compile('^[ \t]*Thread ([a-f0-9]+)')
    line = ''
    while not thread_re.match(line):
      # Skip blank lines. There are typically three or four sections separated
      # by newlines in the header.
      line = line.strip()
      if line:
        parts = line.split(':', 1)
        # Certain lines in different report versions don't follow the key-value
        # format, so skip them.
        if len(parts) == 2:
          # There's a varying amount of space padding after the ':' to align all
          # the values; strip that.
          self.report_info[parts[0]] = parts[1].lstrip()
      line = fd.readline()

    # When this loop exits, the header has been read in full. However, the first
    # thread stack heading has been read past. Seek backwards from the current
    # position by the length of the line so that it is re-read when
    # _ParseStack() is entered.
    fd.seek(-len(line), os.SEEK_CUR)

  def _ParseStack(self, fd):
    """Parses the stack dump of a crash report and creates a list of threads
    and their stack traces."""
    # Compile a regex that matches the start of a thread stack. Note that this
    # must be specific to not include the thread state section, which comes
    # right after all the stack traces.
    line_re = re.compile('^Thread ([0-9]+)( Crashed)?:(.*)')

    # On entry into this function, the fd has been walked up to the "Thread 0"
    # line.
    line = fd.readline().rstrip()
    in_stack = False
    thread = None
    while line_re.match(line) or in_stack:
      # Check for start of the thread stack.
      matches = line_re.match(line)

      if not line.strip():
        # A blank line indicates a break in the thread stack.
        in_stack = False
      elif matches:
        # If this is the start of a thread stack, create the CrashThread.
        in_stack = True
        thread = CrashThread(matches.group(1))
        thread.name = matches.group(3)
        thread.did_crash = matches.group(2) != None
        self.threads.append(thread)
      else:
        # All other lines are stack frames.
        thread.stack.append(self._ParseStackFrame(line))
      # Read the next line.
      line = fd.readline()

  def _ParseStackFrame(self, line):
    """Takes in a single line of text and transforms it into a StackFrame."""
    frame = StackFrame(line)

    # A stack frame is in the format of:
    # |<frame-number> <binary-image> 0x<address> <symbol> <offset>|.
    regex = '^([0-9]+) +(.+)[ \t]+(0x[0-9a-f]+) (.*) \+ ([0-9]+)$'
    matches = re.match(regex, line)
    if matches is None:
      return frame

    # Create a stack frame with the information extracted from the regex.
    frame.frame_id = matches.group(1)
    frame.image = matches.group(2)
    frame.address = int(matches.group(3), 0)  # Convert HEX to an int.
    frame.original_symbol = matches.group(4)
    frame.offset = matches.group(5)
    frame.line = None
    return frame

  def _ParseSpindumpStack(self, fd):
    """Parses a spindump stack report. In this format, each thread stack has
    both a user and kernel trace. Only the user traces are symbolicated."""

    # The stack trace begins with the thread header, which is identified by a
    # HEX number. The thread names appear to be incorrect in spindumps.
    user_thread_re = re.compile('^  Thread ([0-9a-fx]+)')

    # When this method is called, the fd has been walked right up to the first
    # line.
    line = fd.readline()
    in_user_stack = False
    in_kernel_stack = False
    thread = None
    frame_id = 0
    while user_thread_re.match(line) or in_user_stack or in_kernel_stack:
      # Check for the start of a thread.
      matches = user_thread_re.match(line)

      if not line.strip():
        # A blank line indicates the start of a new thread. The blank line comes
        # after the kernel stack before a new thread header.
        in_kernel_stack = False
      elif matches:
        # This is the start of a thread header. The next line is the heading for
        # the user stack, followed by the actual trace.
        thread = CrashThread(matches.group(1))
        frame_id = 0
        self.threads.append(thread)
        in_user_stack = True
        line = fd.readline()  # Read past the 'User stack:' header.
      elif line.startswith('  Kernel stack:'):
        # The kernel stack header comes immediately after the last frame (really
        # the top frame) in the user stack, without a blank line.
        in_user_stack = False
        in_kernel_stack = True
      elif in_user_stack:
        # If this is a line while in the user stack, parse it as a stack frame.
        thread.stack.append(self._ParseSpindumpStackFrame(line))
      # Loop with the next line.
      line = fd.readline()

    # When the loop exits, the file has been read through the 'Binary images:'
    # header. Seek backwards so that _ParseBinaryImages() does the right thing.
    fd.seek(-len(line), os.SEEK_CUR)

  def _ParseSpindumpStackFrame(self, line):
    """Parses a spindump-style stackframe."""
    frame = StackFrame(line)

    # The format of the frame is either:
    # A: |<space><steps> <symbol> + <offset> (in <image-name>) [<address>]|
    # B: |<space><steps> ??? (in <image-name> + <offset>) [<address>]|
    regex_a = '^([ ]+[0-9]+) (.*) \+ ([0-9]+) \(in (.*)\) \[(0x[0-9a-f]+)\]'
    regex_b = '^([ ]+[0-9]+) \?\?\?( \(in (.*) \+ ([0-9]+)\))? \[(0x[0-9a-f]+)\]'

    # Create the stack frame with the information extracted from the regex.
    matches = re.match(regex_a, line)
    if matches:
      frame.frame_id = matches.group(1)[4:]  # Remove some leading spaces.
      frame.original_symbol = matches.group(2)
      frame.offset = matches.group(3)
      frame.image = matches.group(4)
      frame.address = int(matches.group(5), 0)
      frame.line = None
      return frame

    # If pattern A didn't match (which it will most of the time), try B.
    matches = re.match(regex_b, line)
    if matches:
      frame.frame_id = matches.group(1)[4:]  # Remove some leading spaces.
      frame.image = matches.group(3)
      frame.offset = matches.group(4)
      frame.address = int(matches.group(5), 0)
      frame.line = None
      return frame

    # Otherwise, this frame could not be matched and just use the raw input.
    frame.line = frame.line.strip()
    return frame

  def _ParseBinaryImages(self, fd):
    """Parses out the binary images section in order to get the load offset."""
    # The parser skips some sections, so advance until the "Binary Images"
    # header is reached.
    while not fd.readline().lstrip().startswith("Binary Images:"): pass

    # Create a regex to match the lines of format:
    # |0x<start> - 0x<end> <binary-image> <version> (<version>) <<UUID>> <path>|
    image_re = re.compile(
        '[ ]*(0x[0-9a-f]+) -[ \t]+(0x[0-9a-f]+) [+ ]([a-zA-Z0-9._\-]+)')

    # This section is in this format:
    # |<start address> - <end address> <image name>|.
    while True:
      line = fd.readline()
      if not line.strip():
        # End when a blank line is hit.
        return
      # Match the line to the regex.
      match = image_re.match(line)
      if match:
        # Store the offsets by image name so it can be referenced during
        # symbolication. These are hex numbers with leading '0x', so int() can
        # convert them to decimal if base=0.
        address_range = (int(match.group(1), 0), int(match.group(2), 0))
        self._binary_images[match.group(3)] = address_range

  def _CollectAddressesForImages(self, images):
    """Iterates all the threads and stack frames and all the stack frames that
    are in a list of binary |images|. The result is a dictionary, keyed by the
    image name that maps to a list of tuples. Each is a 2-Tuple of
    (stack_frame, address)"""
    # Create the collection and initialize it with empty lists for each image.
    collection = {}
    for image in images:
      collection[image] = []

    # Perform the iteration.
    for thread in self.threads:
      for frame in thread.stack:
        image_name = self._ImageForAddress(frame.address)
        if image_name in images:
          # Replace the image name in the frame in case it was elided.
          frame.image = image_name
          collection[frame.image].append((frame, frame.address))

    # Return the result.
    return collection

  def _ImageForAddress(self, address):
    """Given a PC address, returns the bundle identifier of the image in which
    the address resides."""
    for image_name, address_range in self._binary_images.items():
      if address >= address_range[0] and address <= address_range[1]:
        return image_name
    return None

  def _GetDSymPath(self, base_path, image_name):
    """Takes a base path for the symbols and an image name. It looks the name up
    in SYMBOL_IMAGE_MAP and creates a full path to the dSYM in the bundle."""
    image_file = SYMBOL_IMAGE_MAP[image_name]
    return os.path.join(base_path, image_file + '.dSYM', 'Contents',
        'Resources', 'DWARF',
        os.path.splitext(image_file)[0])  # Chop off the extension.

  def _RunAtos(self, load_address, dsym_file, addresses):
    """Runs the atos with the provided arguments. |addresses| is used as stdin.
    Returns a list of symbol information in the same order as |addresses|."""
    args = ['atos', '-l', str(load_address), '-o', dsym_file]

    # Get the arch type. This is of the format |X86 (Native)|.
    if 'Code Type' in self.report_info:
      arch = self.report_info['Code Type'].lower().split(' ')
      if len(arch) == 2:
        arch = arch[0]
        if arch == 'x86':
          # The crash report refers to i386 as x86, but atos doesn't know what
          # that is.
          arch = 'i386'
        args.extend(['-arch', arch])

    proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    addresses = map(hex, addresses)
    (stdout, stderr) = proc.communicate(' '.join(addresses))
    if proc.returncode:
      return None
    return stdout.rstrip().split('\n')

  def _AddSymbolsToFrames(self, symbols, address_tuples):
    """Takes a single value (the list) from _CollectAddressesForImages and does
    a smart-zip with the data returned by atos in |symbols|. Note that the
    indices must match for this to succeed."""
    if len(symbols) != len(address_tuples):
      print 'symbols do not match'

    # Each line of output from atos is in this format:
    # |<symbol> (in <image>) (<file>:<line>)|.
    line_regex = re.compile('(.+) \(in (.+)\) (\((.+):([0-9]+)\))?')

    # Zip the two data sets together.
    for i in range(len(symbols)):
      symbol_parts = line_regex.match(symbols[i])
      if not symbol_parts:
        continue  # Error.
      frame = address_tuples[i][0]
      frame.symbol = symbol_parts.group(1)
      frame.image = symbol_parts.group(2)
      frame.file_name = symbol_parts.group(4)
      frame.line_number = symbol_parts.group(5)


class CrashThread(object):
  """A CrashThread represents a stacktrace of a single thread """
  def __init__(self, thread_id):
    super(CrashThread, self).__init__()
    self.thread_id = thread_id
    self.name = None
    self.did_crash = False
    self.stack = []

  def __repr__(self):
    name = ''
    if self.name:
      name = ': ' + self.name
    return 'Thread ' + self.thread_id + name + '\n' + \
        '\n'.join(map(str, self.stack))


class StackFrame(object):
  """A StackFrame is owned by a CrashThread."""
  def __init__(self, line):
    super(StackFrame, self).__init__()
    # The original line. This will be set to None if symbolication was
    # successfuly.
    self.line = line

    self.frame_id = 0
    self.image = None
    self.address = 0x0
    self.original_symbol = None
    self.offset = 0x0
    # The following members are set after symbolication.
    self.symbol = None
    self.file_name = None
    self.line_number = 0

  def __repr__(self):
    # If symbolication failed, just use the original line.
    if self.line:
      return '  %s' % self.line

    # Use different location information depending on symbolicated data.
    location = None
    if self.file_name:
      location = ' - %s:%s' % (self.file_name, self.line_number)
    else:
      location = ' + %s' % self.offset

    # Same with the symbol information.
    symbol = self.original_symbol
    if self.symbol:
      symbol = self.symbol

    return '  %s\t0x%x\t[%s\t%s]\t%s' % (self.frame_id, self.address,
        self.image, location, symbol)


def PrettyPrintReport(report):
  """Takes a crash report and prints it like the crash server would."""
  print 'Process    : ' + report.report_info['Process']
  print 'Version    : ' + report.report_info['Version']
  print 'Date       : ' + report.report_info['Date/Time']
  print 'OS Version : ' + report.report_info['OS Version']
  print
  if 'Crashed Thread' in report.report_info:
    print 'Crashed Thread : ' + report.report_info['Crashed Thread']
    print
  if 'Event' in report.report_info:
    print 'Event      : ' + report.report_info['Event']
    print

  for thread in report.threads:
    print
    if thread.did_crash:
      exc_type = report.report_info['Exception Type'].split(' ')[0]
      exc_code = report.report_info['Exception Codes'].replace('at', '@')
      print '*CRASHED* ( ' + exc_type + ' / ' + exc_code + ' )'
    # Version 7 reports have spindump-style output (with a stepped stack trace),
    # so remove the first tab to get better alignment.
    if report.report_version == 7:
      for line in repr(thread).split('\n'):
        print line.replace('\t', '  ', 1)
    else:
      print thread


def Main(args):
  """Program main."""
  parser = optparse.OptionParser(
      usage='%prog [options] symbol_path crash_report',
      description='This will parse and symbolicate an Apple CrashReporter v6-9 '
          'file.')
  parser.add_option('-s', '--std-path', action='store_true', dest='std_path',
                    help='With this flag, the symbol_path is a containing '
                    'directory, in which a dSYM files are stored in a '
                    'directory named by the version. Example: '
                    '[symbolicate_crash.py -s ./symbols/ report.crash] will '
                    'look for dSYMs in ./symbols/15.0.666.0/ if the report is '
                    'from that verison.')
  (options, args) = parser.parse_args(args[1:])

  # Check that we have something to symbolicate.
  if len(args) != 2:
    parser.print_usage()
    return 1

  report = CrashReport(args[1])
  symbol_path = None

  # If not using the standard layout, this is a full path to the symbols.
  if not options.std_path:
    symbol_path = args[0]
  # Otherwise, use the report version to locate symbols in a directory.
  else:
    # This is in the format of |M.N.B.P (B.P)|. Get just the part before the
    # space.
    chrome_version = report.report_info['Version'].split(' ')[0]
    symbol_path = os.path.join(args[0], chrome_version)

  # Check that the symbols exist.
  if not os.path.isdir(symbol_path):
    print >>sys.stderr, 'Symbol path %s is not a directory' % symbol_path
    return 2

  print >>sys.stderr, 'Using symbols from ' + symbol_path
  print >>sys.stderr, '=' * 80

  report.Symbolicate(symbol_path)
  PrettyPrintReport(report)
  return 0


if __name__ == '__main__':
  sys.exit(Main(sys.argv))
