#!/usr/bin/env python
# symbolicate-linux-fatal - Symbolicate Linux stack traces -*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
#
# ----------------------------------------------------------------------------
#
# Symbolicates fatalError stack traces on Linux. Takes the main binary
# and a log file containing a stack trace. Non-stacktrace lines are output
# unmodified. Stack trace elements are analyzed using reconstructed debug
# target matching the original process in where shared libs where mapped.
#
# TODOs:
# * verbose output
# * search symbols by name for the not <unavailable> ones
#
# ----------------------------------------------------------------------------

from __future__ import print_function

import argparse
import os
import subprocess

import lldb


def process_ldd(lddoutput):
    dyn_libs = {}
    for line in lddoutput.splitlines():
        ldd_tokens = line.split()
        if len(ldd_tokens) >= 2:
            lib = ldd_tokens[-2]
            dyn_libs[ldd_tokens[0]] = lib
            real_name = os.path.basename(os.path.realpath(lib)) 
            dyn_libs[real_name] = lib
    return dyn_libs


def create_lldb_target(binary, memmap):
    lldb_debugger = lldb.SBDebugger.Create()
    lldb_target = lldb_debugger.CreateTargetWithFileAndArch(
        binary, lldb.LLDB_ARCH_DEFAULT)
    module = lldb_target.GetModuleAtIndex(0)
    # lldb seems to treat main binary differently, slide offset must be zero
    lldb_target.SetModuleLoadAddress(module, 0)
    for dynlib_path in memmap:
        if binary not in dynlib_path:
            module = lldb_target.AddModule(
                dynlib_path, lldb.LLDB_ARCH_DEFAULT, None, None)
            lldb_target.SetModuleLoadAddress(module, memmap[dynlib_path])
    return lldb_target


def process_stack(binary, dyn_libs, stack):
    if len(stack) == 0:
        return
    memmap = {}
    full_stack = []
    for line in stack:
        stack_tokens = line.split()
        dynlib_fname = stack_tokens[1]
        if dynlib_fname in dyn_libs:
            dynlib_path = dyn_libs[dynlib_fname]
        elif dynlib_fname in binary:
            dynlib_path = binary
        else:
            dynlib_path = None

        if "<unavailable>" in stack_tokens[3]:
            framePC = int(stack_tokens[2], 16)
            symbol_offset = int(stack_tokens[-1], 10)
            dynlib_baseaddr = framePC - symbol_offset
            if dynlib_path in memmap:
                if memmap[dynlib_path] != dynlib_baseaddr:
                    error_msg = "Mismatched base address for: {0:s}, " \
                                "had: {1:x}, now got {2:x}"
                    error_msg = error_msg.format(
                        dynlib_path, memmap[dynlib_path], dynlib_baseaddr)
                    raise Exception(error_msg)
            else:
                memmap[dynlib_path] = dynlib_baseaddr
        else:
            framePC = int(stack_tokens[2], 16) + int(stack_tokens[-1], 10)
        full_stack.append(
            {"line": line, "framePC": framePC, "dynlib_fname": dynlib_fname})

    lldb_target = create_lldb_target(binary, memmap)
    frame_idx = 0
    for frame in full_stack:
        use_orig_line = True
        frame_addr = frame["framePC"]
        dynlib_fname = frame["dynlib_fname"]
        so_addr = lldb_target.ResolveLoadAddress(frame_addr - 1)
        sym_ctx = so_addr.GetSymbolContext(lldb.eSymbolContextEverything)
        frame_fragment = "{0: <4d} {1:20s} 0x{2:016x}".format(
            frame_idx, dynlib_fname, frame_addr)
        symbol = sym_ctx.GetSymbol()
        if symbol.IsValid():
            symbol_base = symbol.GetStartAddress().GetLoadAddress(lldb_target)
            symbol_fragment = "{0:s} + {1:d}".format(
                symbol.GetName(), frame_addr - symbol_base)
            use_orig_line = False
        else:
            symbol_fragment = "<unavailable>"
        line_entry = sym_ctx.GetLineEntry()
        if line_entry.IsValid():
            line_fragment = "at {0:s}:{1:d}".format(
                line_entry.GetFileSpec().GetFilename(), line_entry.GetLine())
        else:
            line_fragment = ""
        if use_orig_line:
            print(frame["line"].rstrip())
        else:
            print("{0:s}    {1:s} {2:s}".format(
                frame_fragment, symbol_fragment, line_fragment))
        frame_idx = frame_idx + 1


def main():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="""Symbolicates stack traces in Linux log files.""")
    parser.add_argument(
        "binary", help="Executable which produced the log file")
    parser.add_argument(
        "log", type=argparse.FileType("rU"),
        help="Log file containing the stack trace to symbolicate")
    args = parser.parse_args()

    binary = args.binary

    lddoutput = subprocess.check_output(
        ['ldd', binary], stderr=subprocess.STDOUT)
    dyn_libs = process_ldd(lddoutput)

    instack = False
    stackidx = 0
    stack = []
    for line in args.log:
        if instack and line.startswith(str(stackidx)):
            stack.append(line)
            stackidx = stackidx + 1
        else:
            instack = False
            stackidx = 0
            process_stack(binary, dyn_libs, stack)
            stack = []
            print(line.rstrip())
        if line.startswith("Current stack trace:"):
            instack = True
    process_stack(binary, dyn_libs, stack)


if __name__ == '__main__':
    main()
