#!/usr/bin/env vpython3
#
# Copyright 2019 The Chromium Authors
# 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  # noqa: E402
from devil.android import device_utils  # noqa: E402
from devil.utils import timeout_retry  # noqa: E402


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())
