# This implements the "diagnose-unwind" command, usually installed
# in the debug session like
#   command script import lldb.diagnose
# it is used when lldb's backtrace fails -- it collects and prints
# information about the stack frames, and tries an alternate unwind
# algorithm, that will help to understand why lldb's unwind algorithm
# did not succeed.
from __future__ import print_function

import optparse
import lldb
import re
import shlex

# Print the frame number, pc, frame pointer, module UUID and function name
# Returns the SBModule that contains the PC, if it could be found


def backtrace_print_frame(target, frame_num, addr, fp):
    process = target.GetProcess()
    addr_for_printing = addr
    addr_width = process.GetAddressByteSize() * 2
    if frame_num > 0:
        addr = addr - 1

    sbaddr = lldb.SBAddress()
    try:
        sbaddr.SetLoadAddress(addr, target)
        module_description = ""
        if sbaddr.GetModule():
            module_filename = ""
            module_uuid_str = sbaddr.GetModule().GetUUIDString()
            if module_uuid_str is None:
                module_uuid_str = ""
            if sbaddr.GetModule().GetFileSpec():
                module_filename = sbaddr.GetModule().GetFileSpec().GetFilename()
                if module_filename is None:
                    module_filename = ""
            if module_uuid_str != "" or module_filename != "":
                module_description = '%s %s' % (
                    module_filename, module_uuid_str)
    except Exception:
        print('%2d: pc==0x%-*x fp==0x%-*x' % (frame_num, addr_width, addr_for_printing, addr_width, fp))
        return

    sym_ctx = target.ResolveSymbolContextForAddress(
        sbaddr, lldb.eSymbolContextEverything)
    if sym_ctx.IsValid() and sym_ctx.GetSymbol().IsValid():
        function_start = sym_ctx.GetSymbol().GetStartAddress().GetLoadAddress(target)
        offset = addr - function_start
        print('%2d: pc==0x%-*x fp==0x%-*x %s %s + %d' % (frame_num, addr_width, addr_for_printing, addr_width, fp, module_description, sym_ctx.GetSymbol().GetName(), offset))
    else:
        print('%2d: pc==0x%-*x fp==0x%-*x %s' % (frame_num, addr_width, addr_for_printing, addr_width, fp, module_description))
    return sbaddr.GetModule()

# A simple stack walk algorithm that follows the frame chain.
# Returns a two-element list; the first element is a list of modules
# seen and the second element is a list of addresses seen during the backtrace.


def simple_backtrace(debugger):
    target = debugger.GetSelectedTarget()
    process = target.GetProcess()
    cur_thread = process.GetSelectedThread()

    initial_fp = cur_thread.GetFrameAtIndex(0).GetFP()

    # If the pseudoreg "fp" isn't recognized, on arm hardcode to r7 which is
    # correct for Darwin programs.
    if initial_fp == lldb.LLDB_INVALID_ADDRESS and target.triple[0:3] == "arm":
        for reggroup in cur_thread.GetFrameAtIndex(1).registers:
            if reggroup.GetName() == "General Purpose Registers":
                for reg in reggroup:
                    if reg.GetName() == "r7":
                        initial_fp = int(reg.GetValue(), 16)

    module_list = []
    address_list = [cur_thread.GetFrameAtIndex(0).GetPC()]
    this_module = backtrace_print_frame(
        target, 0, cur_thread.GetFrameAtIndex(0).GetPC(), initial_fp)
    print_stack_frame(process, initial_fp)
    print("")
    if this_module is not None:
        module_list.append(this_module)
    if cur_thread.GetNumFrames() < 2:
        return [module_list, address_list]

    cur_fp = process.ReadPointerFromMemory(initial_fp, lldb.SBError())
    cur_pc = process.ReadPointerFromMemory(
        initial_fp + process.GetAddressByteSize(), lldb.SBError())

    frame_num = 1

    while cur_pc != 0 and cur_fp != 0 and cur_pc != lldb.LLDB_INVALID_ADDRESS and cur_fp != lldb.LLDB_INVALID_ADDRESS:
        address_list.append(cur_pc)
        this_module = backtrace_print_frame(target, frame_num, cur_pc, cur_fp)
        print_stack_frame(process, cur_fp)
        print("")
        if this_module is not None:
            module_list.append(this_module)
        frame_num = frame_num + 1
        next_pc = 0
        next_fp = 0
        if target.triple[
            0:6] == "x86_64" or target.triple[
            0:4] == "i386" or target.triple[
                0:3] == "arm":
            error = lldb.SBError()
            next_pc = process.ReadPointerFromMemory(
                cur_fp + process.GetAddressByteSize(), error)
            if not error.Success():
                next_pc = 0
            next_fp = process.ReadPointerFromMemory(cur_fp, error)
            if not error.Success():
                next_fp = 0
        # Clear the 0th bit for arm frames - this indicates it is a thumb frame
        if target.triple[0:3] == "arm" and (next_pc & 1) == 1:
            next_pc = next_pc & ~1
        cur_pc = next_pc
        cur_fp = next_fp
    this_module = backtrace_print_frame(target, frame_num, cur_pc, cur_fp)
    print_stack_frame(process, cur_fp)
    print("")
    if this_module is not None:
        module_list.append(this_module)
    return [module_list, address_list]


def print_stack_frame(process, fp):
    if fp == 0 or fp == lldb.LLDB_INVALID_ADDRESS or fp == 1:
        return
    addr_size = process.GetAddressByteSize()
    addr = fp - (2 * addr_size)
    i = 0
    outline = "Stack frame from $fp-%d: " % (2 * addr_size)
    error = lldb.SBError()
    try:
        while i < 5 and error.Success():
            address = process.ReadPointerFromMemory(
                addr + (i * addr_size), error)
            outline += " 0x%x" % address
            i += 1
        print(outline)
    except Exception:
        return


def diagnose_unwind(debugger, command, result, dict):
    """
  Gather diagnostic information to help debug incorrect unwind (backtrace)
  behavior in lldb.  When there is a backtrace that doesn't look
  correct, run this command with the correct thread selected and a
  large amount of diagnostic information will be printed, it is likely
  to be helpful when reporting the problem.
    """

    command_args = shlex.split(command)
    parser = create_diagnose_unwind_options()
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return
    target = debugger.GetSelectedTarget()
    if target:
        process = target.GetProcess()
        if process:
            thread = process.GetSelectedThread()
            if thread:
                lldb_versions_match = re.search(
                    r'[lL][lL][dD][bB]-(\d+)([.](\d+))?([.](\d+))?',
                    debugger.GetVersionString())
                lldb_version = 0
                lldb_minor = 0
                if len(lldb_versions_match.groups()
                       ) >= 1 and lldb_versions_match.groups()[0]:
                    lldb_major = int(lldb_versions_match.groups()[0])
                if len(lldb_versions_match.groups()
                       ) >= 5 and lldb_versions_match.groups()[4]:
                    lldb_minor = int(lldb_versions_match.groups()[4])

                modules_seen = []
                addresses_seen = []

                print('LLDB version %s' % debugger.GetVersionString())
                print('Unwind diagnostics for thread %d' % thread.GetIndexID())
                print("")
                print("=============================================================================================")
                print("")
                print("OS plugin setting:")
                debugger.HandleCommand(
                    "settings show target.process.python-os-plugin-path")
                print("")
                print("Live register context:")
                thread.SetSelectedFrame(0)
                debugger.HandleCommand("register read")
                print("")
                print("=============================================================================================")
                print("")
                print("lldb's unwind algorithm:")
                print("")
                frame_num = 0
                for frame in thread.frames:
                    if not frame.IsInlined():
                        this_module = backtrace_print_frame(
                            target, frame_num, frame.GetPC(), frame.GetFP())
                        print_stack_frame(process, frame.GetFP())
                        print("")
                        if this_module is not None:
                            modules_seen.append(this_module)
                        addresses_seen.append(frame.GetPC())
                        frame_num = frame_num + 1
                print("")
                print("=============================================================================================")
                print("")
                print("Simple stack walk algorithm:")
                print("")
                (module_list, address_list) = simple_backtrace(debugger)
                if module_list and module_list is not None:
                    modules_seen += module_list
                if address_list and address_list is not None:
                    addresses_seen = set(addresses_seen)
                    addresses_seen.update(set(address_list))

                print("")
                print("=============================================================================================")
                print("")
                print("Modules seen in stack walks:")
                print("")
                modules_already_seen = set()
                for module in modules_seen:
                    if module is not None and module.GetFileSpec().GetFilename() is not None:
                        if not module.GetFileSpec().GetFilename() in modules_already_seen:
                            debugger.HandleCommand(
                                'image list %s' %
                                module.GetFileSpec().GetFilename())
                            modules_already_seen.add(
                                module.GetFileSpec().GetFilename())

                print("")
                print("=============================================================================================")
                print("")
                print("Disassembly ofaddresses seen in stack walks:")
                print("")
                additional_addresses_to_disassemble = addresses_seen
                for frame in thread.frames:
                    if not frame.IsInlined():
                        print("--------------------------------------------------------------------------------------")
                        print("")
                        print("Disassembly of %s, frame %d, address 0x%x" % (frame.GetFunctionName(), frame.GetFrameID(), frame.GetPC()))
                        print("")
                        if target.triple[
                                0:6] == "x86_64" or target.triple[
                                0:4] == "i386":
                            debugger.HandleCommand(
                                'disassemble -F att -a 0x%x' % frame.GetPC())
                        else:
                            debugger.HandleCommand(
                                'disassemble -a 0x%x' %
                                frame.GetPC())
                        if frame.GetPC() in additional_addresses_to_disassemble:
                            additional_addresses_to_disassemble.remove(
                                frame.GetPC())

                for address in list(additional_addresses_to_disassemble):
                    print("--------------------------------------------------------------------------------------")
                    print("")
                    print("Disassembly of 0x%x" % address)
                    print("")
                    if target.triple[
                            0:6] == "x86_64" or target.triple[
                            0:4] == "i386":
                        debugger.HandleCommand(
                            'disassemble -F att -a 0x%x' % address)
                    else:
                        debugger.HandleCommand('disassemble -a 0x%x' % address)

                print("")
                print("=============================================================================================")
                print("")
                additional_addresses_to_show_unwind = addresses_seen
                for frame in thread.frames:
                    if not frame.IsInlined():
                        print("--------------------------------------------------------------------------------------")
                        print("")
                        print("Unwind instructions for %s, frame %d" % (frame.GetFunctionName(), frame.GetFrameID()))
                        print("")
                        debugger.HandleCommand(
                            'image show-unwind -a "0x%x"' % frame.GetPC())
                        if frame.GetPC() in additional_addresses_to_show_unwind:
                            additional_addresses_to_show_unwind.remove(
                                frame.GetPC())

                for address in list(additional_addresses_to_show_unwind):
                    print("--------------------------------------------------------------------------------------")
                    print("")
                    print("Unwind instructions for 0x%x" % address)
                    print("")
                    debugger.HandleCommand(
                        'image show-unwind -a "0x%x"' % address)


def create_diagnose_unwind_options():
    usage = "usage: %prog"
    description = '''Print diagnostic information about a thread backtrace which will help to debug unwind problems'''
    parser = optparse.OptionParser(
        description=description,
        prog='diagnose_unwind',
        usage=usage)
    return parser

lldb.debugger.HandleCommand(
    'command script add -f %s.diagnose_unwind diagnose-unwind' %
    __name__)
print('The "diagnose-unwind" command has been installed, type "help diagnose-unwind" for detailed help.')
