#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#
"""
This script can be used to make the output from
apache::thrift::profile_print_info() more human-readable.

It translates each executable file name and address into the corresponding
source file name, line number, and function name.  By default, it also
demangles C++ symbol names.
"""

import optparse
import os
import re
import subprocess
import sys


class AddressInfo(object):
    """
    A class to store information about a particular address in an object file.
    """
    def __init__(self, obj_file, address):
        self.objectFile = obj_file
        self.address = address
        self.sourceFile = None
        self.sourceLine = None
        self.function = None


g_addrs_by_filename = {}
def get_address(filename, address):
    """
    Retrieve an AddressInfo object for the specified object file and address.

    Keeps a global list of AddressInfo objects.  Two calls to get_address()
    with the same filename and address will always return the same AddressInfo
    object.
    """
    global g_addrs_by_filename
    try:
        by_address = g_addrs_by_filename[filename]
    except KeyError:
        by_address = {}
        g_addrs_by_filename[filename] = by_address

    try:
        addr_info = by_address[address]
    except KeyError:
        addr_info = AddressInfo(filename, address)
        by_address[address] = addr_info
    return addr_info


def translate_file_addresses(filename, addresses, options):
    """
    Use addr2line to look up information for the specified addresses.
    All of the addresses must belong to the same object file.
    """
    # Do nothing if we can't find the file
    if not os.path.isfile(filename):
        return

    args = ['addr2line']
    if options.printFunctions:
        args.append('-f')
    args.extend(['-e', filename])

    proc = subprocess.Popen(args, stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE)
    for address in addresses:
        assert address.objectFile == filename
        proc.stdin.write(address.address + '\n')

        if options.printFunctions:
            function = proc.stdout.readline()
            function = function.strip()
            if not function:
                raise Exception('unexpected EOF from addr2line')
            address.function = function

        file_and_line = proc.stdout.readline()
        file_and_line = file_and_line.strip()
        if not file_and_line:
            raise Exception('unexpected EOF from addr2line')
        idx = file_and_line.rfind(':')
        if idx < 0:
            msg = 'expected file and line number from addr2line; got %r' % \
                    (file_and_line,)
            msg += '\nfile=%r, address=%r' % (filename, address.address)
            raise Exception(msg)

        address.sourceFile = file_and_line[:idx]
        address.sourceLine = file_and_line[idx+1:]

    (remaining_out, cmd_err) = proc.communicate()
    retcode = proc.wait()
    if retcode != 0:
        raise subprocess.CalledProcessError(retcode, args)


def lookup_addresses(options):
    """
    Look up source file information for all of the addresses currently stored
    in the global list of AddressInfo objects.
    """
    global g_addrs_by_filename
    for (file, addresses) in g_addrs_by_filename.items():
        translate_file_addresses(file, addresses.values(), options)


class Entry(object):
    """
    An entry in the thrift profile output.
    Contains a header line, and a backtrace.
    """
    def __init__(self, header):
        self.header = header
        self.bt = []

    def addFrame(self, filename, address):
        # If libc was able to determine the symbols names, the filename
        # argument will be of the form <filename>(<function>+<offset>)
        # So, strip off anything after the last '('
        idx = filename.rfind('(')
        if idx >= 0:
            filename = filename[:idx]

        addr = get_address(filename, address)
        self.bt.append(addr)

    def write(self, f, options):
        f.write(self.header)
        f.write('\n')
        n = 0
        for address in self.bt:
            f.write('  #%-2d %s:%s\n' % (n, address.sourceFile,
                                         address.sourceLine))
            n += 1
            if options.printFunctions:
                if address.function:
                    f.write('      %s\n' % (address.function,))
                else:
                    f.write('      ??\n')


def process_file(in_file, out_file, options):
    """
    Read thrift profile output from the specified input file, and print
    prettier information on the output file.
    """
    #
    # A naive approach would be to read the input line by line,
    # and each time we come to a filename and address, pass it to addr2line
    # and print the resulting information.  Unfortunately, addr2line can be
    # quite slow, especially with large executables.
    #
    # This approach is much faster.  We read in all of the input, storing
    # the addresses in each file that need to be resolved.  We then call
    # addr2line just once for each file.  This is much faster than calling
    # addr2line once per address.
    #

    virt_call_regex = re.compile(r'^\s*T_VIRTUAL_CALL: (\d+) calls on (.*):$')
    gen_prot_regex = re.compile(
            r'^\s*T_GENERIC_PROTOCOL: (\d+) calls to (.*) with a (.*):$')
    bt_regex = re.compile(r'^\s*#(\d+)\s*(.*) \[(0x[0-9A-Za-z]+)\]$')

    # Parse all of the input, and store it as Entry objects
    entries = []
    current_entry = None
    while True:
        line = in_file.readline()
        if not line:
            break

        if line == '\n' or line.startswith('Thrift virtual call info:'):
            continue

        virt_call_match = virt_call_regex.match(line)
        if virt_call_match:
            num_calls = int(virt_call_match.group(1))
            type_name = virt_call_match.group(2)
            if options.cxxfilt:
                # Type names reported by typeid() are internal names.
                # By default, c++filt doesn't demangle internal type names.
                # (Some versions of c++filt have a "-t" option to enable this.
                # Other versions don't have this argument, but demangle type
                # names passed as an argument, but not on stdin.)
                #
                # If the output is being filtered through c++filt, prepend
                # "_Z" to the type name to make it look like an external name.
                type_name = '_Z' + type_name
            header = 'T_VIRTUAL_CALL: %d calls on "%s"' % \
                    (num_calls, type_name)
            if current_entry is not None:
                entries.append(current_entry)
            current_entry = Entry(header)
            continue

        gen_prot_match = gen_prot_regex.match(line)
        if gen_prot_match:
            num_calls = int(gen_prot_match.group(1))
            type_name1 = gen_prot_match.group(2)
            type_name2 = gen_prot_match.group(3)
            if options.cxxfilt:
                type_name1 = '_Z' + type_name1
                type_name2 = '_Z' + type_name2
            header = 'T_GENERIC_PROTOCOL: %d calls to "%s" with a "%s"' % \
                    (num_calls, type_name1, type_name2)
            if current_entry is not None:
                entries.append(current_entry)
            current_entry = Entry(header)
            continue

        bt_match = bt_regex.match(line)
        if bt_match:
            if current_entry is None:
                raise Exception('found backtrace frame before entry header')
            frame_num = int(bt_match.group(1))
            filename = bt_match.group(2)
            address = bt_match.group(3)
            current_entry.addFrame(filename, address)
            continue

        raise Exception('unexpected line in input: %r' % (line,))

    # Add the last entry we were processing to the list
    if current_entry is not None:
        entries.append(current_entry)
        current_entry = None

    # Look up all of the addresses
    lookup_addresses(options)

    # Print out the entries, now that the information has been translated
    for entry in entries:
        entry.write(out_file, options)
        out_file.write('\n')


def start_cppfilt():
    (read_pipe, write_pipe) = os.pipe()

    # Fork.  Run c++filt in the parent process,
    # and then continue normal processing in the child.
    pid = os.fork()
    if pid == 0:
        # child
        os.dup2(write_pipe, sys.stdout.fileno())
        os.close(read_pipe)
        os.close(write_pipe)
        return
    else:
        # parent
        os.dup2(read_pipe, sys.stdin.fileno())
        os.close(read_pipe)
        os.close(write_pipe)

        cmd = ['c++filt']
        os.execvp(cmd[0], cmd)


def main(argv):
    parser = optparse.OptionParser(usage='%prog [options] [<file>]')
    parser.add_option('--no-functions', help='Don\'t print function names',
                      dest='printFunctions', action='store_false',
                      default=True)
    parser.add_option('--no-demangle',
                      help='Don\'t demangle C++ symbol names',
                      dest='cxxfilt', action='store_false',
                      default=True)

    (options, args) = parser.parse_args(argv[1:])
    num_args = len(args)
    if num_args == 0:
        in_file = sys.stdin
    elif num_args == 1:
        in_file = open(argv[1], 'r')
    else:
        parser.print_usage(sys.stderr)
        print >> sys.stderr, 'trailing arguments: %s' % (' '.join(args[1:],))
        return 1

    if options.cxxfilt:
        start_cppfilt()

    process_file(in_file, sys.stdout, options)


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