#!/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()
