#!/usr/bin/env vpython
#
# Copyright 2019 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.

# Fetches Crashpad dumps from a given device, walks and symbolizes the stacks.
# All the non-trivial operations are performed by generate_breakpad_symbols.py,
# dump_syms, minidump_dump and minidump_stackwalk.

import argparse
import logging
import os
import posixpath
import re
import sys
import shutil
import subprocess
import tempfile

_BUILD_ANDROID_PATH = os.path.abspath(
    os.path.join(os.path.dirname(__file__), '..'))
sys.path.append(_BUILD_ANDROID_PATH)
import devil_chromium
from devil.android import device_utils
from devil.utils import timeout_retry


def _CreateSymbolsDir(build_path, dynamic_library_names):
  generator = os.path.normpath(
      os.path.join(_BUILD_ANDROID_PATH, '..', '..', 'components', 'crash',
                   'content', 'tools', 'generate_breakpad_symbols.py'))
  syms_dir = os.path.join(build_path, 'crashpad_syms')
  shutil.rmtree(syms_dir, ignore_errors=True)
  os.mkdir(syms_dir)
  for lib in dynamic_library_names:
    unstripped_library_path = os.path.join(build_path, 'lib.unstripped', lib)
    if not os.path.exists(unstripped_library_path):
      continue
    logging.info('Generating symbols for: %s', unstripped_library_path)
    cmd = [
        generator,
        '--symbols-dir',
        syms_dir,
        '--build-dir',
        build_path,
        '--binary',
        unstripped_library_path,
        '--platform',
        'android',
    ]
    return_code = subprocess.call(cmd)
    if return_code != 0:
      logging.error('Could not extract symbols, command failed: %s',
                    ' '.join(cmd))
  return syms_dir


def _ChooseLatestCrashpadDump(device, crashpad_dump_path):
  if not device.PathExists(crashpad_dump_path):
    logging.warning('Crashpad dump directory does not exist: %s',
                    crashpad_dump_path)
    return None
  latest = None
  latest_timestamp = 0
  for crashpad_file in device.ListDirectory(crashpad_dump_path):
    if crashpad_file.endswith('.dmp'):
      stat = device.StatPath(posixpath.join(crashpad_dump_path, crashpad_file))
      current_timestamp = stat['st_mtime']
      if current_timestamp > latest_timestamp:
        latest_timestamp = current_timestamp
        latest = crashpad_file
  return latest


def _ExtractLibraryNamesFromDump(build_path, dump_path):
  default_library_name = 'libmonochrome.so'
  dumper_path = os.path.join(build_path, 'minidump_dump')
  if not os.access(dumper_path, os.X_OK):
    logging.warning(
        'Cannot extract library name from dump because %s is not found, '
        'default to: %s', dumper_path, default_library_name)
    return [default_library_name]
  p = subprocess.Popen([dumper_path, dump_path],
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE)
  stdout, stderr = p.communicate()
  if p.returncode != 0:
    # Dumper errors often do not affect stack walkability, just a warning.
    logging.warning('Reading minidump failed with output:\n%s', stderr)

  library_names = []
  module_library_line_re = re.compile(r'[(]code_file[)]\s+= '
                                      r'"(?P<library_name>lib[^. ]+.so)"')
  in_module = False
  for line in stdout.splitlines():
    line = line.lstrip().rstrip('\n')
    if line == 'MDRawModule':
      in_module = True
      continue
    if line == '':
      in_module = False
      continue
    if in_module:
      m = module_library_line_re.match(line)
      if m:
        library_names.append(m.group('library_name'))
  if not library_names:
    logging.warning(
        'Could not find any library name in the dump, '
        'default to: %s', default_library_name)
    return [default_library_name]
  return library_names


def main():
  logging.basicConfig(level=logging.INFO)
  parser = argparse.ArgumentParser(
      description='Fetches Crashpad dumps from a given device, '
      'walks and symbolizes the stacks.')
  parser.add_argument('--device', required=True, help='Device serial number')
  parser.add_argument('--adb-path', help='Path to the "adb" command')
  parser.add_argument(
      '--build-path',
      required=True,
      help='Build output directory, equivalent to CHROMIUM_OUTPUT_DIR')
  parser.add_argument(
      '--chrome-cache-path',
      required=True,
      help='Directory on the device where Chrome stores cached files,'
      ' crashpad stores dumps in a subdirectory of it')
  args = parser.parse_args()

  stackwalk_path = os.path.join(args.build_path, 'minidump_stackwalk')
  if not os.path.exists(stackwalk_path):
    logging.error('Missing minidump_stackwalk executable')
    return 1

  devil_chromium.Initialize(output_directory=args.build_path,
                            adb_path=args.adb_path)
  device = device_utils.DeviceUtils(args.device)

  device_crashpad_path = posixpath.join(args.chrome_cache_path, 'Crashpad',
                                        'pending')

  def CrashpadDumpExists():
    return _ChooseLatestCrashpadDump(device, device_crashpad_path)

  crashpad_file = timeout_retry.WaitFor(
      CrashpadDumpExists, wait_period=1, max_tries=9)
  if not crashpad_file:
    logging.error('Could not locate a crashpad dump')
    return 1

  dump_dir = tempfile.mkdtemp()
  symbols_dir = None
  try:
    device.PullFile(
        device_path=posixpath.join(device_crashpad_path, crashpad_file),
        host_path=dump_dir)
    dump_full_path = os.path.join(dump_dir, crashpad_file)
    library_names = _ExtractLibraryNamesFromDump(args.build_path,
                                                 dump_full_path)
    symbols_dir = _CreateSymbolsDir(args.build_path, library_names)
    stackwalk_cmd = [stackwalk_path, dump_full_path, symbols_dir]
    subprocess.call(stackwalk_cmd)
  finally:
    shutil.rmtree(dump_dir, ignore_errors=True)
    if symbols_dir:
      shutil.rmtree(symbols_dir, ignore_errors=True)
  return 0


if __name__ == '__main__':
  sys.exit(main())
