#!/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 subprocess

import lldb


def process_ldd(lddoutput):
    dyn_libs = {}
    for line in lddoutput.splitlines():
        ldd_tokens = line.split()
        if len(ldd_tokens) >= 3:
            dyn_libs[ldd_tokens[0]] = ldd_tokens[2]
    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()
