#!/usr/bin/env python
#
# Copyright (C) 2018 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Symbolizes stack traces from logcat.
See https://developer.android.com/ndk/guides/ndk-stack for more information.
"""

from __future__ import print_function

import argparse
import os
import re
import shutil
import subprocess
import sys
import tempfile
import zipfile

EXE_SUFFIX = '.exe' if os.name == 'nt' else ''


class TmpDir(object):
    """Manage temporary directory creation."""

    def __init__(self):
        self._tmp_dir = None

    def delete(self):
        if self._tmp_dir:
            shutil.rmtree(self._tmp_dir)

    def get_directory(self):
        if not self._tmp_dir:
            self._tmp_dir = tempfile.mkdtemp()
        return self._tmp_dir


def get_ndk_paths():
    """Parse and find all of the paths of the ndk

    Returns: Three values:
             Full path to the root of the ndk install.
             Full path to the ndk bin directory where this executable lives.
             The platform name (eg linux-x86_64).
    """

    # ndk-stack is installed to $NDK/prebuilt/<platform>/bin, so from
    # `android-ndk-r18/prebuilt/linux-x86_64/bin/ndk-stack`...
    # ...get `android-ndk-r18/`:
    ndk_bin = os.path.dirname(os.path.realpath(__file__))
    ndk_root = os.path.abspath(os.path.join(ndk_bin, '../../..'))
    # ...get `linux-x86_64`:
    ndk_host_tag = os.path.basename(
        os.path.abspath(os.path.join(ndk_bin, '../')))
    return (ndk_root, ndk_bin, ndk_host_tag)


def find_llvm_symbolizer(ndk_root, ndk_bin, ndk_host_tag):
    """Finds the NDK llvm-symbolizer(1) binary.

    Returns: An absolute path to llvm-symbolizer(1).
    """

    llvm_symbolizer = 'llvm-symbolizer' + EXE_SUFFIX
    path = os.path.join(ndk_root, 'toolchains', 'llvm', 'prebuilt',
                        ndk_host_tag, 'bin', llvm_symbolizer)
    if os.path.exists(path):
        return path

    # Okay, maybe we're a standalone toolchain? (https://github.com/android-ndk/ndk/issues/931)
    # In that case, llvm-symbolizer and ndk-stack are conveniently in
    # the same directory...
    path = os.path.abspath(os.path.join(ndk_bin, llvm_symbolizer))
    if os.path.exists(path):
        return path
    raise OSError('Unable to find llvm-symbolizer')


def find_readelf(ndk_root, ndk_bin, ndk_host_tag):
    """Finds the NDK readelf(1) binary.

    Returns: An absolute path to readelf(1).
    """

    readelf = 'llvm-readelf' + EXE_SUFFIX
    m = re.match('^[^-]+-(.*)', ndk_host_tag)
    if m:
        # Try as if this is not a standalone install.
        arch = m.group(1)
        path = os.path.join(ndk_root, 'toolchains', 'llvm', 'prebuilt',
                            ndk_host_tag, 'bin', readelf)
        if os.path.exists(path):
            return path

    # Might be a standalone toolchain.
    path = os.path.normpath(os.path.join(ndk_bin, readelf))
    if os.path.exists(path):
        return path
    return None


def get_build_id(readelf_path, elf_file):
    """Get the GNU build id note from an elf file.

    Returns: The build id found or None if there is no build id or the
             readelf path does not exist.
    """

    try:
        output = subprocess.check_output([readelf_path, '-n', elf_file])
        m = re.search(r'Build ID:\s+([0-9a-f]+)', output.decode())
        if not m:
            return None
        return m.group(1)
    except subprocess.CalledProcessError:
        return None


def get_zip_info_from_offset(zip_file, offset):
    """Get the ZipInfo object from a zip file.

    Returns: A ZipInfo object found at the 'offset' into the zip file.
             Returns None if no file can be found at the given 'offset'.
    """

    file_size = os.stat(zip_file.filename).st_size
    if offset >= file_size:
        return None

    infos = zip_file.infolist()
    if not infos or offset < infos[0].header_offset:
        return None

    for i in range(1, len(infos)):
        prev_info = infos[i - 1]
        cur_offset = infos[i].header_offset
        if offset >= prev_info.header_offset and offset < cur_offset:
            zip_info = prev_info
            return zip_info
    zip_info = infos[len(infos) - 1]
    if offset < zip_info.header_offset:
        return None
    return zip_info


class FrameInfo(object):
    """A class to represent the data in a single backtrace frame.

    Attributes:
      num: The string representing the frame number (eg #01).
      pc: The relative program counter for the frame.
      elf_file: The file or map name in which the relative pc resides.
      container_file: The name of the file that contains the elf_file.
                      For example, an entry like GoogleCamera.apk!libsome.so
                      would set container_file to GoogleCamera.apk and
                      set elf_file to libsome.so. Set to None if no ! found.
      offset: The offset into the file at which this library was mapped.
              Set to None if no offset found.
      build_id: The Gnu build id note parsed from the frame information.
                Set to None if no build id found.
      tail: The part of the line after the program counter.
    """

    # See unwindstack::FormatFrame in libunwindstack.
    # We're deliberately very loose because NDK users are likely to be
    # looking at crashes on ancient OS releases.
    # TODO: support asan stacks too?
    _line_re = re.compile(r'.* +(#[0-9]+) +pc ([0-9a-f]+) +(([^ ]+).*)')
    _sanitizer_line_re = re.compile(r'.* +(#[0-9]+) +0x[0-9a-f]* +\(([^ ]+)\+0x([0-9a-f]+)\)')
    _lib_re = re.compile(r'([^\!]+)\!(.+)')
    _offset_re = re.compile(r'\(offset\s+(0x[0-9a-f]+)\)')
    _build_id_re = re.compile(r'\(BuildId:\s+([0-9a-f]+)\)')

    @classmethod
    def from_line(cls, line):
        m = FrameInfo._line_re.match(line)
        if m:
          return cls(*m.group(1, 2, 3, 4))
        m = FrameInfo._sanitizer_line_re.match(line)
        if m:
          return cls(*m.group(1, 3, 2, 2), sanitizer=True)
        return None

    def __init__(self, num, pc, tail, elf_file, sanitizer=False):
        self.num = num
        self.pc = pc
        self.tail = tail
        self.elf_file = elf_file
        self.sanitizer = sanitizer
        m = FrameInfo._lib_re.match(self.elf_file)
        if m:
            self.container_file = m.group(1)
            self.elf_file = m.group(2)
            # Sometimes an entry like this will occur:
            #   #01 pc 0000abcd  /system/lib/lib/libc.so!libc.so (offset 0x1000)
            # In this case, no container file should be set.
            if os.path.basename(self.container_file) == os.path.basename(
                    self.elf_file):
                self.elf_file = self.container_file
                self.container_file = None
        else:
            self.container_file = None
        m = FrameInfo._offset_re.search(self.tail)
        if m:
            self.offset = int(m.group(1), 16)
        else:
            self.offset = None
        m = FrameInfo._build_id_re.search(self.tail)
        if m:
            self.build_id = m.group(1)
        else:
            self.build_id = None

    def verify_elf_file(self, readelf_path, elf_file_path, display_elf_path):
        """Verify if the elf file is valid.

        Returns: True if the elf file exists and build id matches (if it exists).
        """

        if not os.path.exists(elf_file_path):
            return False
        if readelf_path and self.build_id:
            build_id = get_build_id(readelf_path, elf_file_path)
            if self.build_id != build_id:
                print(
                    'WARNING: Mismatched build id for %s' % (display_elf_path))
                print('WARNING:   Expected %s' % (self.build_id))
                print('WARNING:   Found    %s' % (build_id))
                return False
        return True

    def get_elf_file(self, symbol_dir, readelf_path, tmp_dir):
        """Get the path to the elf file represented by this frame.

        Returns: The path to the elf file if it is valid, or None if
                 no valid elf file can be found. If the file has to be
                 extracted from an apk, the elf file will be placed in
                 tmp_dir.
        """

        elf_file = os.path.basename(self.elf_file)
        if self.container_file:
            # This matches a file format such as Base.apk!libsomething.so
            # so see if we can find libsomething.so in the symbol directory.
            elf_file_path = os.path.join(symbol_dir, elf_file)
            if self.verify_elf_file(readelf_path, elf_file_path,
                                    elf_file_path):
                return elf_file_path

            apk_file_path = os.path.join(symbol_dir,
                                         os.path.basename(self.container_file))
            with zipfile.ZipFile(apk_file_path) as zip_file:
                zip_info = get_zip_info_from_offset(zip_file, self.offset)
                if not zip_info:
                    return None
                elf_file_path = zip_file.extract(zip_info,
                                                 tmp_dir.get_directory())
                display_elf_file = '%s!%s' % (apk_file_path, elf_file)
                if not self.verify_elf_file(readelf_path, elf_file_path,
                                            display_elf_file):
                    return None
                return elf_file_path
        elif elf_file[-4:] == '.apk':
            # This matches a stack line such as:
            #   #08 pc 00cbed9c  GoogleCamera.apk (offset 0x6e32000)
            apk_file_path = os.path.join(symbol_dir, elf_file)
            with zipfile.ZipFile(apk_file_path) as zip_file:
                zip_info = get_zip_info_from_offset(zip_file, self.offset)
                if not zip_info:
                    return None

                # Rewrite the output tail so that it goes from:
                #   GoogleCamera.apk ...
                # To:
                #   GoogleCamera.apk!libsomething.so ...
                index = self.tail.find(elf_file)
                if index != -1:
                    index += len(elf_file)
                    self.tail = (self.tail[0:index] + '!' + os.path.basename(
                        zip_info.filename) + self.tail[index:])
                elf_file = os.path.basename(zip_info.filename)
                elf_file_path = os.path.join(symbol_dir, elf_file)
                if self.verify_elf_file(readelf_path, elf_file_path,
                                        elf_file_path):
                    return elf_file_path

                elf_file_path = zip_file.extract(zip_info,
                                                 tmp_dir.get_directory())
                display_elf_path = '%s!%s' % (apk_file_path, elf_file)
                if not self.verify_elf_file(readelf_path, elf_file_path,
                                            display_elf_path):
                    return None
                return elf_file_path
        elf_file_path = os.path.join(symbol_dir, elf_file)
        if self.verify_elf_file(readelf_path, elf_file_path, elf_file_path):
            return elf_file_path
        return None


def main(argv):
    """"Program entry point."""
    parser = argparse.ArgumentParser(
        description='Symbolizes Android crashes.',
        epilog='See <https://developer.android.com/ndk/guides/ndk-stack>.')
    parser.add_argument(
        '-sym',
        '--sym',
        dest='symbol_dir',
        required=True,  # TODO: default to '.'?
        help='directory containing unstripped .so files')
    parser.add_argument(
        '-i',
        '-dump',
        '--dump',
        dest='input',
        default=sys.stdin,
        type=argparse.FileType('r'),
        help='input filename')
    args = parser.parse_args(argv)

    if not os.path.exists(args.symbol_dir):
        sys.exit('{} does not exist!\n'.format(args.symbol_dir))

    ndk_paths = get_ndk_paths()
    symbolize_cmd = [
        find_llvm_symbolizer(*ndk_paths), '--demangle', '--functions=linkage',
        '--inlines'
    ]
    readelf_path = find_readelf(*ndk_paths)

    symbolize_proc = None
    try:
        tmp_dir = TmpDir()
        symbolize_proc = subprocess.Popen(
            symbolize_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        banner = '*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***'
        in_crash = False
        saw_frame = False
        for line in args.input:
            line = line.rstrip()

            if not in_crash:
                if banner in line:
                    in_crash = True
                    saw_frame = False
                    print('********** Crash dump: **********')
                continue

            for tag in ['Build fingerprint:', 'Abort message:']:
                if tag in line:
                    print(line[line.find(tag):])
                    continue

            frame_info = FrameInfo.from_line(line)
            if not frame_info:
                if saw_frame:
                    in_crash = False
                    print('Crash dump is completed\n')
                continue

            # There can be a gap between sanitizer frames in the abort message
            # and the actual backtrace. Do not end the crash dump until we've
            # seen the actual backtrace.
            if not frame_info.sanitizer:
              saw_frame = True

            try:
                elf_file = frame_info.get_elf_file(args.symbol_dir,
                                                   readelf_path, tmp_dir)
            except IOError:
                elf_file = None

            # Print a slightly different version of the stack trace line.
            # The original format:
            #      #00 pc 0007b350  /lib/bionic/libc.so (__strchr_chk+4)
            # becomes:
            #      #00 0x0007b350 /lib/bionic/libc.so (__strchr_chk+4)
            out_line = '%s 0x%s %s' % (frame_info.num, frame_info.pc,
                                       frame_info.tail)
            print(out_line)
            indent = (out_line.find('(') + 1) * ' '
            if not elf_file:
                continue
            value = '"%s" 0x%s\n' % (elf_file, frame_info.pc)
            symbolize_proc.stdin.write(value.encode())
            symbolize_proc.stdin.flush()
            while True:
                symbolizer_output = symbolize_proc.stdout.readline().rstrip()
                if not symbolizer_output:
                    break
                # TODO: rewrite file names base on a source path?
                print('%s%s' % (indent, symbolizer_output.decode()))
    finally:
        args.input.close()
        tmp_dir.delete()
        if symbolize_proc:
            symbolize_proc.stdin.close()
            symbolize_proc.stdout.close()
            symbolize_proc.kill()
            symbolize_proc.wait()


if __name__ == '__main__':
    main(sys.argv[1:])
