#!/usr/bin/env python
#
# Copyright (C) 2017 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.
#

"""debug_unwind_reporter.py: report dwarf unwinding results generated by debug-unwind cmd.
    Below is an example using debug_unwind_reporter.py:
    1. Record with "-g --no-unwind" option on device.
       simpleperf record -g --no-unwind --app com.google.sample.tunnel --duration 10
    2. Use debug-unwind cmd to unwind samples in perf.data on device.
       simpleperf debug-unwind
    3. Pull perf.data.debug on host, and report it with this script.
       python debug_unwind_reporter.py

    It reports below items:
    1. time used for offline dwarf unwinding for each sample.
    2. mem consumption before and after unwinding samples.
    3. For samples that don't have complete callchains, report their regs, stack data,
       unwinding failure info, callchains. Samples having the same failure reason
       in the same function are only reported once.

    It can be used to:
    1. show unwinding failures.
    2. show performance and memory consumption change caused by simpleperf/unwinder changes.
"""

from __future__ import print_function
import argparse
import bisect
import collections
import copy
import re
import subprocess

from utils import bytes_to_str, log_exit, log_fatal, get_host_binary_path


class MapEntry(object):

    def __init__(self, start, end, filename):
        self.start = start
        self.end = end
        self.filename = filename

    def __lt__(self, other):
        return self.start < other.start

class ProcessMaps(object):

    def __init__(self):
        self.process_maps = {}  # map from pid to a sorted list of MapEntry.

    def add(self, pid, map_entry):
        old_list = self.process_maps.get(pid, [])
        new_list = []
        map_entry_used = False
        for entry in old_list:
            if entry.end <= map_entry.start:
                new_list.append(entry)
            elif entry.start < map_entry.start:
                entry.end = map_entry.start
                new_list.append(entry)
            else:
                if not map_entry_used:
                    new_list.append(map_entry)
                    map_entry_used = True
                if entry.start >= map_entry.end:
                    new_list.append(entry)
                elif entry.end > map_entry.end:
                    entry.start = map_entry.end
                    new_list.append(entry)
        if not map_entry_used:
            new_list.append(map_entry)
        self.process_maps[pid] = new_list

    def fork_pid(self, pid, ppid):
        if pid == ppid:
            return
        entry_list = self.process_maps.get(ppid, [])
        self.process_maps[pid] = copy.deepcopy(entry_list)

    def find(self, pid, addr):
        key = MapEntry(addr, addr, '')
        entry_list = self.process_maps.get(pid, [])
        pos = bisect.bisect_right(entry_list, key)
        if pos > 0 and entry_list[pos - 1].end > addr:
            return entry_list[pos - 1]
        return None

    def show(self):
        for pid in sorted(self.process_maps):
            print('  pid %d' % pid)
            for entry in self.process_maps[pid]:
                print('    map [%x-%x] %s' %
                      (entry.start, entry.end, entry.filename))


class UnwindingTimes(object):

    def __init__(self):
        self.total_time = 0
        self.count = 0
        self.max_time = 0

    def add_time(self, used_time):
        self.total_time += used_time
        self.count += 1
        self.max_time = max(self.max_time, used_time)


class UnwindingMemConsumption(object):

    def __init__(self):
        self.before_unwinding = None
        self.after_unwinding = None


class CallChainNode(object):

    """ Representing a node in a call chain."""

    def __init__(self, ip, sp, filename, vaddr_in_file, function_name, map_start_addr,
                 map_end_addr):
        self.ip = ip
        self.sp = sp
        self.filename = filename
        self.vaddr_in_file = vaddr_in_file
        self.function_name = function_name
        self.map_start_addr = map_start_addr
        self.map_end_addr = map_end_addr


class SampleResult(object):

    """ Unwinding result per sample. """

    def __init__(self, pid, tid, unwinding_result, callchain, sample_record):
        self.pid = pid
        self.tid = tid
        self.unwinding_result = unwinding_result
        self.callchain = callchain
        self.sample_record = sample_record

    def show(self):
        print('  pid: %d' % self.pid)
        print('  tid: %d' % self.tid)
        for key, value in self.unwinding_result.items():
            print('  %s: %s' % (key, value))
        for i, node in enumerate(self.callchain):
            print('  node %d: ip 0x%x, sp 0x%x, %s (%s[+%x]), map [%x-%x]' % (
                i, node.ip, node.sp, node.function_name, node.filename, node.vaddr_in_file,
                node.map_start_addr, node.map_end_addr))
        if self.sample_record:
            print('  original sample record:')
            for line in self.sample_record:
                print('    %s' % line)


class FunctionResult(object):

    """ Unwinding result per function. """

    def __init__(self):
        # Map from Unwinding result reason to [SampleResult].
        self.sample_results = {}

    def add_sample_result(self, sample_result):
        stop_reason = sample_result.unwinding_result['stop_reason']
        result_list = self.sample_results.get(stop_reason)
        if not result_list:
            result_list = self.sample_results[stop_reason] = []
        for result in result_list:
            if result.callchain[-1].vaddr_in_file == sample_result.callchain[-1].vaddr_in_file:
                # This sample_result duplicates with an existing one.
                return
        # We don't want to store too many sample results for a function.
        if len(result_list) < 10:
            result_list.append(sample_result)

    def show(self):
        for stop_reason in sorted(self.sample_results):
            for sample_result in self.sample_results[stop_reason]:
                sample_result.show()


class FileResult(object):

    """ Unwinding result per shared library. """

    def __init__(self):
        self.function_results = {}  # Map from function_name to FunctionResult.

    def add_sample_result(self, sample_result):
        function_name = sample_result.callchain[-1].function_name
        function_result = self.function_results.get(function_name)
        if not function_result:
            function_result = self.function_results[
                function_name] = FunctionResult()
        function_result.add_sample_result(sample_result)

    def show(self):
        for function_name in sorted(self.function_results):
            print('  function %s' % function_name)
            self.function_results[function_name].show()
            print('\n')


class UnwindingResultErrorReport(object):

    """ Report time used for unwinding and unwinding result errors. """

    def __init__(self, omit_callchains_fixed_by_joiner):
        self.omit_callchains_fixed_by_joiner = omit_callchains_fixed_by_joiner
        self.process_maps = ProcessMaps()
        self.unwinding_times = UnwindingTimes()
        self.mem_stat = UnwindingMemConsumption()
        self.file_results = {}  # map from filename to FileResult.

    def add_sample_result(self, sample_result, joined_record):
        self.unwinding_times.add_time(int(sample_result.unwinding_result['used_time']))
        if self.should_omit(sample_result, joined_record):
            return
        filename = sample_result.callchain[-1].filename
        file_result = self.file_results.get(filename)
        if not file_result:
            file_result = self.file_results[filename] = FileResult()
        file_result.add_sample_result(sample_result)

    def add_mem_stat(self, name, mem_str):
        # mem_str is like VmPeak:202464 kB;VmSize:183456 kB;VmHWM:98256 kB;VmRSS:33680 kB.
        items = []
        for p in mem_str.split(';'):
            key, value = p.split(':')
            items.append((key, value))
        if name == 'debug_unwind_mem_before':
            self.mem_stat.before_unwinding = items
        else:
            self.mem_stat.after_unwinding = items

    def should_omit(self, sample_result, joined_record):
        # 1. Can't unwind code generated in memory.
        for name in ['/dev/ashmem/dalvik-jit-code-cache', '[anon:dalvik-jit-code-cache]', '//anon']:
            if name in sample_result.callchain[-1].filename:
                return True
        # 2. Don't report complete callchains, which can reach __libc_init or __start_thread in
        # libc.so.
        def is_callchain_complete(callchain):
            for node in callchain:
                if (node.filename.endswith('libc.so') and
                        node.function_name in ['__libc_init', '__start_thread']):
                    return True
            return False
        if is_callchain_complete(sample_result.callchain):
            return True
        # 3. Omit callchains made complete by callchain joiner.
        if self.omit_callchains_fixed_by_joiner and is_callchain_complete(joined_record.callchain):
            return True
        return False

    def show(self):
        print('Unwinding time info:')
        print('  total time: %f ms' % (self.unwinding_times.total_time / 1e6))
        print('  unwinding count: %d' % self.unwinding_times.count)
        if self.unwinding_times.count > 0:
            print('  average time: %f us' % (
                self.unwinding_times.total_time / 1e3 / self.unwinding_times.count))
        print('  max time: %f us' % (self.unwinding_times.max_time / 1e3))
        print('Unwinding mem info:')
        for items in zip(self.mem_stat.before_unwinding, self.mem_stat.after_unwinding):
            assert items[0][0] == items[1][0]
            print('  %s: %s -> %s' % (items[0][0], items[0][1], items[1][1]))
        print('Process maps:')
        self.process_maps.show()
        for filename in sorted(self.file_results):
            print('filename %s' % filename)
            self.file_results[filename].show()
            print('\n')


class CallChainRecord(object):
    """ Store data of a callchain record. """

    def __init__(self):
        self.pid = None
        self.tid = None
        self.callchain = []

def parse_sample_record(lines, i):
    """ Read the lines belong to a SampleRecord."""
    if i == len(lines) or not lines[i].startswith('record sample:'):
        log_fatal('unexpected dump output near line %d' % i)
    start_line = i
    i += 1
    while i < len(lines) and (not lines[i] or lines[i].startswith(' ')):
        i += 1
    return i, lines[start_line:i]

def parse_callchain_record(lines, i, chain_type, process_maps):
    if i == len(lines) or not lines[i].startswith('record callchain:'):
        log_fatal('unexpected dump output near line %d' % i)
    i += 1
    record = CallChainRecord()
    ips = []
    sps = []
    function_names = []
    filenames = []
    vaddr_in_files = []
    map_start_addrs = []
    map_end_addrs = []
    in_callchain = False
    while i < len(lines) and not lines[i].startswith('record'):
        line = lines[i].strip()
        items = line.split()
        if not items:
            i += 1
            continue
        if items[0] == 'pid' and len(items) == 2:
            record.pid = int(items[1])
        elif items[0] == 'tid' and len(items) == 2:
            record.tid = int(items[1])
        elif items[0] == 'chain_type' and len(items) == 2:
            if items[1] != chain_type:
                log_fatal('unexpected dump output near line %d' % i)
        elif items[0] == 'ip':
            m = re.search(r'ip\s+0x(\w+),\s+sp\s+0x(\w+)$', line)
            if m:
                ips.append(int(m.group(1), 16))
                sps.append(int(m.group(2), 16))
        elif items[0] == 'callchain:':
            in_callchain = True
        elif in_callchain:
            # "dalvik-jit-code-cache (deleted)[+346c] ([anon:dalvik-jit-code-cache]
            #  (deleted)[+346c])"
            if re.search(r'\)\[\+\w+\]\)$', line):
                break_pos = line.rfind('(', 0, line.rfind('('))
            else:
                break_pos = line.rfind('(')
            if break_pos > 0:
                m = re.match(r'(.*)\[\+(\w+)\]\)', line[break_pos + 1:])
                if m:
                    function_names.append(line[:break_pos].strip())
                    filenames.append(m.group(1))
                    vaddr_in_files.append(int(m.group(2), 16))
        i += 1

    for ip in ips:
        map_entry = process_maps.find(record.pid, ip)
        if map_entry:
            map_start_addrs.append(map_entry.start)
            map_end_addrs.append(map_entry.end)
        else:
            map_start_addrs.append(0)
            map_end_addrs.append(0)
    n = len(ips)
    if (None in [record.pid, record.tid] or n == 0 or len(sps) != n or
            len(function_names) != n or len(filenames) != n or len(vaddr_in_files) != n or
            len(map_start_addrs) != n or len(map_end_addrs) != n):
        log_fatal('unexpected dump output near line %d' % i)
    for j in range(n):
        record.callchain.append(CallChainNode(ips[j], sps[j], filenames[j], vaddr_in_files[j],
                                              function_names[j], map_start_addrs[j],
                                              map_end_addrs[j]))
    return i, record


def build_unwinding_result_report(args):
    simpleperf_path = get_host_binary_path('simpleperf')
    proc = subprocess.Popen([simpleperf_path, 'dump', args.record_file[0]],
                            stdout=subprocess.PIPE)
    (stdoutdata, _) = proc.communicate()
    stdoutdata = bytes_to_str(stdoutdata)
    if 'debug_unwind = true' not in stdoutdata:
        log_exit("Can't parse unwinding result. Because " +
                 "%s was not generated by the debug-unwind cmd." % args.record_file[0])
    unwinding_report = UnwindingResultErrorReport(args.omit_callchains_fixed_by_joiner)
    process_maps = unwinding_report.process_maps
    lines = stdoutdata.split('\n')
    i = 0
    while i < len(lines):
        if lines[i].startswith('record mmap:') or lines[i].startswith('record mmap2:'):
            i += 1
            pid = None
            start = None
            end = None
            filename = None
            while i < len(lines) and not lines[i].startswith('record'):
                if lines[i].startswith('  pid'):
                    m = re.search(r'pid\s+(\d+).+addr\s+0x(\w+).+len\s+0x(\w+)', lines[i])
                    if m:
                        pid = int(m.group(1))
                        start = int(m.group(2), 16)
                        end = start + int(m.group(3), 16)
                elif 'filename' in lines[i]:
                    pos = lines[i].find('filename') + len('filename')
                    filename = lines[i][pos:].strip()
                i += 1
            if None in [pid, start, end, filename]:
                log_fatal('unexpected dump output near line %d' % i)
            process_maps.add(pid, MapEntry(start, end, filename))
        elif lines[i].startswith('record unwinding_result:'):
            i += 1
            unwinding_result = collections.OrderedDict()
            while i < len(lines) and not lines[i].startswith('record'):
                strs = (lines[i].strip()).split()
                if len(strs) == 2:
                    unwinding_result[strs[0]] = strs[1]
                i += 1
            for key in ['time', 'used_time', 'stop_reason']:
                if key not in unwinding_result:
                    log_fatal('unexpected dump output near line %d' % i)

            i, sample_record = parse_sample_record(lines, i)
            i, original_record = parse_callchain_record(lines, i, 'ORIGINAL_OFFLINE', process_maps)
            i, joined_record = parse_callchain_record(lines, i, 'JOINED_OFFLINE', process_maps)
            if args.omit_sample:
                sample_record = []
            sample_result = SampleResult(original_record.pid, original_record.tid,
                                         unwinding_result, original_record.callchain,
                                         sample_record)
            unwinding_report.add_sample_result(sample_result, joined_record)
        elif lines[i].startswith('record fork:'):
            i += 1
            pid = None
            ppid = None
            while i < len(lines) and not lines[i].startswith('record'):
                if lines[i].startswith('  pid'):
                    m = re.search(r'pid\s+(\w+),\s+ppid\s+(\w+)', lines[i])
                    if m:
                        pid = int(m.group(1))
                        ppid = int(m.group(2))
                i += 1
            if None in [pid, ppid]:
                log_fatal('unexpected dump output near line %d' % i)
            process_maps.fork_pid(pid, ppid)
        elif lines[i].startswith('    debug_unwind_mem'):
            items = lines[i].strip().split(' = ')
            if len(items) == 2:
                unwinding_report.add_mem_stat(items[0], items[1])
            i += 1
        else:
            i += 1
    return unwinding_report


def main():
    parser = argparse.ArgumentParser(
        description='Report dwarf unwinding results generated by the debug-unwind cmd.')
    parser.add_argument('-i', '--record_file', nargs=1, default=['perf.data.debug'], help="""
                        Set profiling data to report. Default is perf.data.debug.""")
    parser.add_argument('--omit-callchains-fixed-by-joiner', action='store_true', help="""
                        Don't show incomplete callchains fixed by callchain joiner.""")
    parser.add_argument('--omit-sample', action='store_true', help="""Don't show original sample
                        records.""")
    args = parser.parse_args()
    report = build_unwinding_result_report(args)
    report.show()

if __name__ == '__main__':
    main()
