#!/usr/bin/env python
#
# Copyright 2006 Google Inc. All Rights Reserved.

"""stack symbolizes native crash dumps."""

import getopt
import getpass
import glob
import os
import re
import subprocess
import sys
import urllib

import symbol


def PrintUsage():
  """Print usage and exit with error."""
  # pylint: disable-msg=C6310
  print
  print "  usage: " + sys.argv[0] + " [options] [FILE]"
  print
  print "  --symbols-dir=path"
  print "       the path to a symbols dir, such as =/tmp/out/target/product/dream/symbols"
  print
  print "  --symbols-zip=path"
  print "       the path to a symbols zip file, such as =dream-symbols-12345.zip"
  print
  print "  --auto"
  print "       attempt to:"
  print "         1) automatically find the build number in the crash"
  print "         2) if it's an official build, download the symbols "
  print "            from the build server, and use them"
  print
  print "  FILE should contain a stack trace in it somewhere"
  print "       the tool will find that and re-print it with"
  print "       source files and line numbers.  If you don't"
  print "       pass FILE, or if file is -, it reads from"
  print "       stdin."
  print
  # pylint: enable-msg=C6310
  sys.exit(1)


class SSOCookie(object):
  """Creates a cookie file so we can download files from the build server."""

  def __init__(self, cookiename=".sso.cookie", keep=False):
    self.sso_server = "login.corp.google.com"
    self.name = cookiename
    self.keeper = keep
    if not os.path.exists(self.name):
      user = os.environ["USER"]
      print "\n%s, to access the symbols, please enter your LDAP " % user,
      sys.stdout.flush()
      password = getpass.getpass()
      params = urllib.urlencode({"u": user, "pw": password})
      url = "https://%s/login?ssoformat=CORP_SSO" % self.sso_server
      # login to SSO
      curlcmd = ["/usr/bin/curl",
                 "--cookie", self.name,
                 "--cookie-jar", self.name,
                 "--silent",
                 "--location",
                 "--data", params,
                 "--output", "/dev/null",
                 url]
      subprocess.check_call(curlcmd)
      if os.path.exists(self.name):
        os.chmod(self.name, 0600)
      else:
        print "Could not log in to SSO"
        sys.exit(1)

  def __del__(self):
    """Clean up."""
    if not self.keeper:
      os.remove(self.name)


class NoBuildIDException(Exception):
  pass


def FindBuildFingerprint(lines):
  """Searches the given file (array of lines) for the build fingerprint."""
  fingerprint_regex = re.compile("^.*Build fingerprint:\s'(?P<fingerprint>.*)'")
  for line in lines:
    fingerprint_search = fingerprint_regex.match(line.strip())
    if fingerprint_search:
      return fingerprint_search.group("fingerprint")

  return None  # didn't find the fingerprint string, so return none


class SymbolDownloadException(Exception):
  pass


DEFAULT_SYMROOT = "/tmp/symbols"


def DownloadSymbols(fingerprint, cookie):
  """Attempts to download the symbols from the build server.

  If successful, extracts them, and returns the path.

  Args:
    fingerprint: build fingerprint from the input stack trace
    cookie: SSOCookie

  Returns:
    tuple (None, None) if no fingerprint is provided. Otherwise
    tuple (root directory, symbols directory).

  Raises:
    SymbolDownloadException: Problem downloading symbols for fingerprint
  """
  if fingerprint is None:
    return (None, None)
  symdir = "%s/%s" % (DEFAULT_SYMROOT, hash(fingerprint))
  if not os.path.exists(symdir):
    os.makedirs(symdir)
  # build server figures out the branch based on the CL
  params = {
      "op": "GET-SYMBOLS-LINK",
      "fingerprint": fingerprint,
      }
  print "url: http://android-build/buildbot-update?" + urllib.urlencode(params)
  url = urllib.urlopen("http://android-build/buildbot-update?",
                       urllib.urlencode(params)).readlines()[0]
  if not url:
    raise SymbolDownloadException("Build server down? Failed to find syms...")

  regex_str = (r"(?P<base_url>http\:\/\/android-build\/builds\/.*\/[0-9]+)"
               r"(?P<img>.*)")
  url_regex = re.compile(regex_str)
  url_match = url_regex.match(url)
  if url_match is None:
    raise SymbolDownloadException("Unexpected results from build server URL...")

  base_url = url_match.group("base_url")
  img = url_match.group("img")
  symbolfile = img.replace("-img-", "-symbols-")
  symurl = base_url + symbolfile
  localsyms = symdir + symbolfile

  if not os.path.exists(localsyms):
    print "downloading %s ..." % symurl
    curlcmd = ["/usr/bin/curl",
               "--cookie", cookie.name,
               "--silent",
               "--location",
               "--write-out", "%{http_code}",
               "--output", localsyms,
               symurl]
    p = subprocess.Popen(curlcmd,
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                         close_fds=True)
    code = p.stdout.read()
    err = p.stderr.read()
    if err:
      raise SymbolDownloadException("stderr from curl download: %s" % err)
    if code != "200":
      raise SymbolDownloadException("Faied to download %s" % symurl)
  else:
    print "using existing cache for symbols"

  return UnzipSymbols(localsyms, symdir)


def UnzipSymbols(symbolfile, symdir=None):
  """Unzips a file to DEFAULT_SYMROOT and returns the unzipped location.

  Args:
    symbolfile: The .zip file to unzip
    symdir: Optional temporary directory to use for extraction

  Returns:
    A tuple containing (the directory into which the zip file was unzipped,
    the path to the "symbols" directory in the unzipped file).  To clean
    up, the caller can delete the first element of the tuple.

  Raises:
    SymbolDownloadException: When the unzip fails.
  """
  if not symdir:
    symdir = "%s/%s" % (DEFAULT_SYMROOT, hash(symbolfile))
  if not os.path.exists(symdir):
    os.makedirs(symdir)

  print "extracting %s..." % symbolfile
  saveddir = os.getcwd()
  os.chdir(symdir)
  try:
    unzipcode = subprocess.call(["unzip", "-qq", "-o", symbolfile])
    if unzipcode > 0:
      os.remove(symbolfile)
      raise SymbolDownloadException("failed to extract symbol files (%s)."
                                    % symbolfile)
  finally:
    os.chdir(saveddir)

  return (symdir, glob.glob("%s/out/target/product/*/symbols" % symdir)[0])


def PrintTraceLines(trace_lines):
  """Print back trace."""
  maxlen = max(map(lambda tl: len(tl[1]), trace_lines))
  print
  print "Stack Trace:"
  print "  RELADDR   " + "FUNCTION".ljust(maxlen) + "  FILE:LINE"
  for tl in trace_lines:
    (addr, symbol_with_offset, location) = tl
    print "  %8s  %s  %s" % (addr, symbol_with_offset.ljust(maxlen), location)
  return


def PrintValueLines(value_lines):
  """Print stack data values."""
  print
  print "Stack Data:"
  print "  ADDR      VALUE     FILE:LINE/FUNCTION"
  for vl in value_lines:
    (addr, value, symbol_with_offset, location) = vl
    print "  " + addr + "  " + value + "  " + location
    if location:
      print "                      " + symbol_with_offset
  return

UNKNOWN = "<unknown>"
HEAP = "[heap]"
STACK = "[stack]"


def ConvertTrace(lines):
  """Convert strings containing native crash to a stack."""
  process_info_line = re.compile("(pid: [0-9]+, tid: [0-9]+.*)")
  signal_line = re.compile("(signal [0-9]+ \(.*\).*)")
  register_line = re.compile("(([ ]*[0-9a-z]{2} [0-9a-f]{8}){4})")
  thread_line = re.compile("(.*)(\-\-\- ){15}\-\-\-")
  # Note taht both trace and value line matching allow for variable amounts of
  # whitespace (e.g. \t). This is because the we want to allow for the stack
  # tool to operate on AndroidFeedback provided system logs. AndroidFeedback
  # strips out double spaces that are found in tombsone files and logcat output.
  #
  # Examples of matched trace lines include lines from tombstone files like:
  #   #00  pc 001cf42e  /data/data/com.my.project/lib/libmyproject.so
  # Or lines from AndroidFeedback crash report system logs like:
  #   03-25 00:51:05.520 I/DEBUG ( 65): #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so
  # Please note the spacing differences.
  trace_line = re.compile("(.*)\#([0-9]+)[ \t]+(..)[ \t]+([0-9a-f]{8})[ \t]+([^\r\n \t]*)( \((.*)\))?")  # pylint: disable-msg=C6310
  # Examples of matched value lines include:
  #   bea4170c  8018e4e9  /data/data/com.my.project/lib/libmyproject.so
  #   03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so
  # Again, note the spacing differences.
  value_line = re.compile("(.*)([0-9a-f]{8})[ \t]+([0-9a-f]{8})[ \t]+([^\r\n \t]*)")
  # Lines from 'code around' sections of the output will be matched before
  # value lines because otheriwse the 'code around' sections will be confused as
  # value lines.
  #
  # Examples include:
  #   801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
  #   03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
  code_line = re.compile("(.*)[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[ \r\n]")  # pylint: disable-msg=C6310

  trace_lines = []
  value_lines = []

  for ln in lines:
    # AndroidFeedback adds zero width spaces into its crash reports. These
    # should be removed or the regular expresssions will fail to match.
    line = unicode(ln, errors='ignore')
    header = process_info_line.search(line)
    if header:
      print header.group(1)
      continue
    header = signal_line.search(line)
    if header:
      print header.group(1)
      continue
    header = register_line.search(line)
    if header:
      print header.group(1)
      continue
    if trace_line.match(line):
      match = trace_line.match(line)
      (unused_0, unused_1, unused_2,
       code_addr, area, symbol_present, symbol_name) = match.groups()

      if area == UNKNOWN or area == HEAP or area == STACK:
        trace_lines.append((code_addr, area, area))
      else:
        # If a calls b which further calls c and c is inlined to b, we want to
        # display "a -> b -> c" in the stack trace instead of just "a -> c"
        (source_symbol,
         source_location,
         object_symbol_with_offset) = symbol.SymbolInformation(area, code_addr)
        if not source_symbol:
          if symbol_present:
            source_symbol = symbol.CallCppFilt(symbol_name)
          else:
            source_symbol = UNKNOWN
        if not source_location:
          source_location = area
        if not object_symbol_with_offset:
          object_symbol_with_offset = source_symbol
        if not object_symbol_with_offset.startswith(source_symbol):
          trace_lines.append(("v------>", source_symbol, source_location))
          trace_lines.append((code_addr,
                              object_symbol_with_offset,
                              source_location))
        else:
          trace_lines.append((code_addr,
                              object_symbol_with_offset,
                              source_location))
    if code_line.match(line):
      # Code lines should be ignored. If this were exluded the 'code around'
      # sections would trigger value_line matches.
      continue;
    if value_line.match(line):
      match = value_line.match(line)
      (unused_, addr, value, area) = match.groups()
      if area == UNKNOWN or area == HEAP or area == STACK or not area:
        value_lines.append((addr, value, area, ""))
      else:
        (source_symbol,
         source_location,
         object_symbol_with_offset) = symbol.SymbolInformation(area, value)
        if not source_location:
          source_location = ""
        if not object_symbol_with_offset:
          object_symbol_with_offset = UNKNOWN
        value_lines.append((addr,
                            value,
                            object_symbol_with_offset,
                            source_location))
    header = thread_line.search(line)
    if header:
      if trace_lines:
        PrintTraceLines(trace_lines)

      if value_lines:
        PrintValueLines(value_lines)
      trace_lines = []
      value_lines = []
      print
      print "-----------------------------------------------------\n"

  if trace_lines:
    PrintTraceLines(trace_lines)

  if value_lines:
    PrintValueLines(value_lines)


def main():
  try:
    options, arguments = getopt.getopt(sys.argv[1:], "",
                                       ["auto",
                                        "symbols-dir=",
                                        "symbols-zip=",
                                        "help"])
  except getopt.GetoptError, unused_error:
    PrintUsage()

  zip_arg = None
  auto = False
  fingerprint = None
  for option, value in options:
    if option == "--help":
      PrintUsage()
    elif option == "--symbols-dir":
      symbol.SYMBOLS_DIR = os.path.expanduser(value)
    elif option == "--symbols-zip":
      zip_arg = os.path.expanduser(value)
    elif option == "--auto":
      auto = True

  if len(arguments) > 1:
    PrintUsage()

  if auto:
    cookie = SSOCookie(".symbols.cookie")

  if not arguments or arguments[0] == "-":
    print "Reading native crash info from stdin"
    f = sys.stdin
  else:
    print "Searching for native crashes in %s" % arguments[0]
    f = open(arguments[0], "r")

  lines = f.readlines()
  f.close()

  rootdir = None
  if auto:
    fingerprint = FindBuildFingerprint(lines)
    print "fingerprint:", fingerprint
    rootdir, symbol.SYMBOLS_DIR = DownloadSymbols(fingerprint, cookie)
  elif zip_arg:
    rootdir, symbol.SYMBOLS_DIR = UnzipSymbols(zip_arg)

  print "Reading symbols from", symbol.SYMBOLS_DIR
  ConvertTrace(lines)

  if rootdir:
    # be a good citizen and clean up...os.rmdir and os.removedirs() don't work
    cmd = "rm -rf \"%s\"" % rootdir
    print "\ncleaning up (%s)" % cmd
    os.system(cmd)

if __name__ == "__main__":
  main()

# vi: ts=2 sw=2
