#!/usr/bin/env python3

# ----------------------------------------------------------------------
# Be sure to add the python path that points to the LLDB shared library.
#
# To use this in the embedded python interpreter using "lldb":
#
#   cd /path/containing/crashlog.py
#   lldb
#   (lldb) script import crashlog
#   "crashlog" command installed, type "crashlog --help" for detailed help
#   (lldb) crashlog ~/Library/Logs/DiagnosticReports/a.crash
#
# The benefit of running the crashlog command inside lldb in the
# embedded python interpreter is when the command completes, there
# will be a target with all of the files loaded at the locations
# described in the crash log. Only the files that have stack frames
# in the backtrace will be loaded unless the "--load-all" option
# has been specified. This allows users to explore the program in the
# state it was in right at crash time.
#
# On MacOSX csh, tcsh:
#   ( setenv PYTHONPATH /path/to/LLDB.framework/Resources/Python ; ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash )
#
# On MacOSX sh, bash:
#   PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash
# ----------------------------------------------------------------------

import abc
import argparse
import concurrent.futures
import contextlib
import datetime
import enum
import json
import os
import platform
import plistlib
import re
import shlex
import string
import subprocess
import sys
import tempfile
import threading
import time
import uuid

print_lock = threading.RLock()

try:
    # First try for LLDB in case PYTHONPATH is already correctly setup.
    import lldb
except ImportError:
    # Ask the command line driver for the path to the lldb module. Copy over
    # the environment so that SDKROOT is propagated to xcrun.
    command = (
        ["xcrun", "lldb", "-P"] if platform.system() == "Darwin" else ["lldb", "-P"]
    )
    # Extend the PYTHONPATH if the path exists and isn't already there.
    lldb_python_path = subprocess.check_output(command).decode("utf-8").strip()
    if os.path.exists(lldb_python_path) and not sys.path.__contains__(lldb_python_path):
        sys.path.append(lldb_python_path)
    # Try importing LLDB again.
    try:
        import lldb
    except ImportError:
        print(
            "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
        )
        sys.exit(1)

from lldb.utils import symbolication
from lldb.plugins.scripted_process import INTEL64_GPR, ARM64_GPR


class CrashLog(symbolication.Symbolicator):
    class Thread:
        """Class that represents a thread in a darwin crash log"""

        def __init__(self, index, app_specific_backtrace, arch):
            self.index = index
            self.id = index
            self.images = list()
            self.frames = list()
            self.idents = list()
            self.registers = dict()
            self.reason = None
            self.name = None
            self.queue = None
            self.crashed = False
            self.app_specific_backtrace = app_specific_backtrace
            self.arch = arch

        def dump_registers(self, prefix=""):
            registers_info = None
            sorted_registers = {}

            def sort_dict(d):
                sorted_keys = list(d.keys())
                sorted_keys.sort()
                return {k: d[k] for k in sorted_keys}

            if self.arch:
                if "x86_64" == self.arch:
                    registers_info = INTEL64_GPR
                elif "arm64" in self.arch:
                    registers_info = ARM64_GPR
                else:
                    print("unknown target architecture: %s" % self.arch)
                    return

                # Add registers available in the register information dictionary.
                for reg_info in registers_info:
                    reg_name = None
                    if reg_info["name"] in self.registers:
                        reg_name = reg_info["name"]
                    elif (
                        "generic" in reg_info and reg_info["generic"] in self.registers
                    ):
                        reg_name = reg_info["generic"]
                    else:
                        # Skip register that are present in the register information dictionary but not present in the report.
                        continue

                    reg_val = self.registers[reg_name]
                    sorted_registers[reg_name] = reg_val

                unknown_parsed_registers = {}
                for reg_name in self.registers:
                    if reg_name not in sorted_registers:
                        unknown_parsed_registers[reg_name] = self.registers[reg_name]

                sorted_registers.update(sort_dict(unknown_parsed_registers))

            else:
                sorted_registers = sort_dict(self.registers)

            for reg_name, reg_val in sorted_registers.items():
                print("%s    %-8s = %#16.16x" % (prefix, reg_name, reg_val))

        def dump(self, prefix=""):
            if self.app_specific_backtrace:
                print(
                    "%Application Specific Backtrace[%u] %s"
                    % (prefix, self.index, self.reason)
                )
            else:
                print("%sThread[%u] %s" % (prefix, self.index, self.reason))
            if self.frames:
                print("%s  Frames:" % (prefix))
                for frame in self.frames:
                    frame.dump(prefix + "    ")
            if self.registers:
                print("%s  Registers:" % (prefix))
                self.dump_registers(prefix)

        def dump_symbolicated(self, crash_log, options):
            this_thread_crashed = self.app_specific_backtrace
            if not this_thread_crashed:
                this_thread_crashed = self.did_crash()
                if options.crashed_only and not this_thread_crashed:
                    return

            print("%s" % self)
            display_frame_idx = -1
            for frame_idx, frame in enumerate(self.frames):
                disassemble = (
                    this_thread_crashed or options.disassemble_all_threads
                ) and frame_idx < options.disassemble_depth

                # Except for the zeroth frame, we should subtract 1 from every
                # frame pc to get the previous line entry.
                pc = frame.pc & crash_log.addr_mask
                pc = pc if frame_idx == 0 or pc == 0 else pc - 1
                symbolicated_frame_addresses = crash_log.symbolicate(
                    pc, options.verbose
                )

                if symbolicated_frame_addresses:
                    symbolicated_frame_address_idx = 0
                    for symbolicated_frame_address in symbolicated_frame_addresses:
                        display_frame_idx += 1
                        print("[%3u] %s" % (frame_idx, symbolicated_frame_address))
                        if (
                            (options.source_all or self.did_crash())
                            and display_frame_idx < options.source_frames
                            and options.source_context
                        ):
                            source_context = options.source_context
                            line_entry = (
                                symbolicated_frame_address.get_symbol_context().line_entry
                            )
                            if line_entry.IsValid():
                                strm = lldb.SBStream()
                                if line_entry:
                                    crash_log.debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers(
                                        line_entry.file,
                                        line_entry.line,
                                        source_context,
                                        source_context,
                                        "->",
                                        strm,
                                    )
                                source_text = strm.GetData()
                                if source_text:
                                    # Indent the source a bit
                                    indent_str = "    "
                                    join_str = "\n" + indent_str
                                    print(
                                        "%s%s"
                                        % (
                                            indent_str,
                                            join_str.join(source_text.split("\n")),
                                        )
                                    )
                        if symbolicated_frame_address_idx == 0:
                            if disassemble:
                                instructions = (
                                    symbolicated_frame_address.get_instructions()
                                )
                                if instructions:
                                    print()
                                    symbolication.disassemble_instructions(
                                        crash_log.get_target(),
                                        instructions,
                                        frame.pc,
                                        options.disassemble_before,
                                        options.disassemble_after,
                                        frame.index > 0,
                                    )
                                    print()
                        symbolicated_frame_address_idx += 1
                else:
                    print(frame)
            if self.registers:
                print()
                self.dump_registers()
            elif self.crashed:
                print()
                print("No thread state (register information) available")

        def add_ident(self, ident):
            if ident not in self.idents:
                self.idents.append(ident)

        def did_crash(self):
            return self.crashed

        def __str__(self):
            if self.app_specific_backtrace:
                s = "Application Specific Backtrace[%u]" % self.index
            else:
                s = "Thread[%u]" % self.index
            if self.reason:
                s += " %s" % self.reason
            return s

    class Frame:
        """Class that represents a stack frame in a thread in a darwin crash log"""

        def __init__(self, index, pc, description, inlined=False):
            self.pc = pc
            self.description = description
            self.index = index
            self.inlined = inlined

        def __str__(self):
            if self.description:
                return "[%3u] 0x%16.16x %s" % (self.index, self.pc, self.description)
            else:
                return "[%3u] 0x%16.16x" % (self.index, self.pc)

        def dump(self, prefix):
            print("%s%s" % (prefix, str(self)))

    class DarwinImage(symbolication.Image):
        """Class that represents a binary images in a darwin crash log"""

        dsymForUUIDBinary = "/usr/local/bin/dsymForUUID"
        if "LLDB_APPLE_DSYMFORUUID_EXECUTABLE" in os.environ:
            dsymForUUIDBinary = os.environ["LLDB_APPLE_DSYMFORUUID_EXECUTABLE"]
        elif not os.path.exists(dsymForUUIDBinary):
            try:
                dsymForUUIDBinary = (
                    subprocess.check_output("which dsymForUUID", shell=True)
                    .decode("utf-8")
                    .rstrip("\n")
                )
            except:
                dsymForUUIDBinary = ""

        dwarfdump_uuid_regex = re.compile(r"UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*")

        def __init__(
            self, text_addr_lo, text_addr_hi, identifier, version, uuid, path, verbose
        ):
            symbolication.Image.__init__(self, path, uuid)
            self.add_section(
                symbolication.Section(text_addr_lo, text_addr_hi, "__TEXT")
            )
            self.identifier = identifier
            self.version = version
            self.verbose = verbose

        def show_symbol_progress(self):
            """
            Hide progress output and errors from system frameworks as they are plentiful.
            """
            if self.verbose:
                return True
            return not (
                self.path.startswith("/System/Library/")
                or self.path.startswith("/usr/lib/")
            )

        def find_matching_slice(self):
            dwarfdump_cmd_output = subprocess.check_output(
                'dwarfdump --uuid "%s"' % self.path, shell=True
            ).decode("utf-8")
            self_uuid = self.get_uuid()
            for line in dwarfdump_cmd_output.splitlines():
                match = self.dwarfdump_uuid_regex.search(line)
                if match:
                    dwarf_uuid_str = match.group(1)
                    dwarf_uuid = uuid.UUID(dwarf_uuid_str)
                    if self_uuid == dwarf_uuid:
                        self.resolved_path = self.path
                        self.arch = match.group(2)
                        return True
            if not self.resolved_path:
                self.unavailable = True
                if self.show_symbol_progress():
                    print(
                        (
                            "error\n    error: unable to locate '%s' with UUID %s"
                            % (self.path, self.get_normalized_uuid_string())
                        )
                    )
                return False

        def locate_module_and_debug_symbols(self):
            # Don't load a module twice...
            if self.resolved:
                return True
            # Mark this as resolved so we don't keep trying
            self.resolved = True
            uuid_str = self.get_normalized_uuid_string()
            if self.show_symbol_progress():
                with print_lock:
                    print("Getting symbols for %s %s..." % (uuid_str, self.path))
            # Keep track of unresolved source paths.
            unavailable_source_paths = set()
            if os.path.exists(self.dsymForUUIDBinary):
                dsym_for_uuid_command = (
                    "{} --copyExecutable --ignoreNegativeCache {}".format(
                        self.dsymForUUIDBinary, uuid_str
                    )
                )
                s = subprocess.check_output(dsym_for_uuid_command, shell=True)
                if s:
                    try:
                        plist_root = plistlib.loads(s)
                    except:
                        with print_lock:
                            print(
                                (
                                    "Got exception: ",
                                    sys.exc_info()[1],
                                    " handling dsymForUUID output: \n",
                                    s,
                                )
                            )
                        raise
                    if plist_root:
                        plist = plist_root[uuid_str]
                        if plist:
                            if "DBGArchitecture" in plist:
                                self.arch = plist["DBGArchitecture"]
                            if "DBGDSYMPath" in plist:
                                self.symfile = os.path.realpath(plist["DBGDSYMPath"])
                            if "DBGSymbolRichExecutable" in plist:
                                self.path = os.path.expanduser(
                                    plist["DBGSymbolRichExecutable"]
                                )
                                self.resolved_path = self.path
                            if "DBGSourcePathRemapping" in plist:
                                path_remapping = plist["DBGSourcePathRemapping"]
                                for _, value in path_remapping.items():
                                    source_path = os.path.expanduser(value)
                                    if not os.path.exists(source_path):
                                        unavailable_source_paths.add(source_path)
            if not self.resolved_path and os.path.exists(self.path):
                if not self.find_matching_slice():
                    return False
            if not self.resolved_path and not os.path.exists(self.path):
                try:
                    mdfind_results = (
                        subprocess.check_output(
                            [
                                "/usr/bin/mdfind",
                                "com_apple_xcode_dsym_uuids == %s" % uuid_str,
                            ]
                        )
                        .decode("utf-8")
                        .splitlines()
                    )
                    found_matching_slice = False
                    for dsym in mdfind_results:
                        dwarf_dir = os.path.join(dsym, "Contents/Resources/DWARF")
                        if not os.path.exists(dwarf_dir):
                            # Not a dSYM bundle, probably an Xcode archive.
                            continue
                        with print_lock:
                            print('falling back to binary inside "%s"' % dsym)
                        self.symfile = dsym
                        # Look for the executable next to the dSYM bundle.
                        parent_dir = os.path.dirname(dsym)
                        executables = []
                        for root, _, files in os.walk(parent_dir):
                            for file in files:
                                abs_path = os.path.join(root, file)
                                if os.path.isfile(abs_path) and os.access(
                                    abs_path, os.X_OK
                                ):
                                    executables.append(abs_path)
                        for binary in executables:
                            basename = os.path.basename(binary)
                            if basename == self.identifier:
                                self.path = binary
                                found_matching_slice = True
                                break
                        if found_matching_slice:
                            break
                except:
                    pass
            if (self.resolved_path and os.path.exists(self.resolved_path)) or (
                self.path and os.path.exists(self.path)
            ):
                with print_lock:
                    print("Resolved symbols for %s %s..." % (uuid_str, self.path))
                    if len(unavailable_source_paths):
                        for source_path in unavailable_source_paths:
                            print(
                                "Could not access remapped source path for %s %s"
                                % (uuid_str, source_path)
                            )
                return True
            else:
                self.unavailable = True
            return False

    def __init__(self, debugger, path, verbose):
        """CrashLog constructor that take a path to a darwin crash log file"""
        symbolication.Symbolicator.__init__(self, debugger)
        self.path = os.path.expanduser(path)
        self.info_lines = list()
        self.system_profile = list()
        self.threads = list()
        self.backtraces = list()  # For application specific backtraces
        self.idents = (
            list()
        )  # A list of the required identifiers for doing all stack backtraces
        self.errors = list()
        self.exception = dict()
        self.crashed_thread_idx = -1
        self.version = -1
        self.target = None
        self.verbose = verbose
        self.process_id = None
        self.process_identifier = None
        self.process_path = None
        self.process_arch = None

    def dump(self):
        print("Crash Log File: %s" % (self.path))
        if self.backtraces:
            print("\nApplication Specific Backtraces:")
            for thread in self.backtraces:
                thread.dump("  ")
        print("\nThreads:")
        for thread in self.threads:
            thread.dump("  ")
        print("\nImages:")
        for image in self.images:
            image.dump("  ")

    def set_main_image(self, identifier):
        for i, image in enumerate(self.images):
            if image.identifier == identifier:
                self.images.insert(0, self.images.pop(i))
                break

    def find_image_with_identifier(self, identifier):
        for image in self.images:
            if image.identifier == identifier:
                return image
        regex_text = r"^.*\.%s$" % (re.escape(identifier))
        regex = re.compile(regex_text)
        for image in self.images:
            if regex.match(image.identifier):
                return image
        return None

    def create_target(self):
        if self.target is None:
            self.target = symbolication.Symbolicator.create_target(self)
            if self.target:
                return self.target
            # We weren't able to open the main executable as, but we can still
            # symbolicate
            print("crashlog.create_target()...2")
            if self.idents:
                for ident in self.idents:
                    image = self.find_image_with_identifier(ident)
                    if image:
                        self.target = image.create_target(self.debugger)
                        if self.target:
                            return self.target  # success
            print("crashlog.create_target()...3")
            for image in self.images:
                self.target = image.create_target(self.debugger)
                if self.target:
                    return self.target  # success
            print("crashlog.create_target()...4")
            print("error: Unable to locate any executables from the crash log.")
            print("       Try loading the executable into lldb before running crashlog")
            print(
                "       and/or make sure the .dSYM bundles can be found by Spotlight."
            )
        return self.target

    def get_target(self):
        return self.target

    def load_images(self, options, loaded_images=None):
        if not loaded_images:
            loaded_images = []
        images_to_load = self.images
        if options.load_all_images:
            for image in self.images:
                image.resolve = True
        elif options.crashed_only:
            images_to_load = []
            for thread in self.threads:
                if thread.did_crash() or thread.app_specific_backtrace:
                    for ident in thread.idents:
                        for image in self.find_images_with_identifier(ident):
                            image.resolve = True
                            images_to_load.append(image)

        futures = []
        with tempfile.TemporaryDirectory() as obj_dir:

            def add_module(image, target, obj_dir):
                return image, image.add_module(target, obj_dir)

            max_worker = None
            if options.no_parallel_image_loading:
                max_worker = 1

            with concurrent.futures.ThreadPoolExecutor(max_worker) as executor:
                for image in images_to_load:
                    if image not in loaded_images:
                        if image.uuid == uuid.UUID(int=0):
                            continue
                        futures.append(
                            executor.submit(
                                add_module,
                                image=image,
                                target=self.target,
                                obj_dir=obj_dir,
                            )
                        )

                for future in concurrent.futures.as_completed(futures):
                    image, err = future.result()
                    if err:
                        print(err)
                    else:
                        loaded_images.append(image)


class CrashLogFormatException(Exception):
    pass


class CrashLogParseException(Exception):
    pass


class InteractiveCrashLogException(Exception):
    pass


class CrashLogParser:
    @staticmethod
    def create(debugger, path, options):
        data = JSONCrashLogParser.is_valid_json(path)
        if data:
            parser = JSONCrashLogParser(debugger, path, options)
            parser.data = data
            return parser
        else:
            return TextCrashLogParser(debugger, path, options)

    def __init__(self, debugger, path, options):
        self.path = os.path.expanduser(path)
        self.options = options
        self.crashlog = CrashLog(debugger, self.path, self.options.verbose)

    @abc.abstractmethod
    def parse(self):
        pass


class JSONCrashLogParser(CrashLogParser):
    @staticmethod
    def is_valid_json(path):
        def parse_json(buffer):
            try:
                return json.loads(buffer)
            except:
                # The first line can contain meta data. Try stripping it and
                # try again.
                head, _, tail = buffer.partition("\n")
                return json.loads(tail)

        with open(path, "r", encoding="utf-8") as f:
            buffer = f.read()
        try:
            return parse_json(buffer)
        except:
            return None

    def __init__(self, debugger, path, options):
        super().__init__(debugger, path, options)

    def parse(self):
        try:
            self.parse_process_info(self.data)
            self.parse_images(self.data["usedImages"])
            self.parse_main_image(self.data)
            self.parse_threads(self.data["threads"])
            if "asi" in self.data:
                self.crashlog.asi = self.data["asi"]
            # FIXME: With the current design, we can either show the ASI or Last
            # Exception Backtrace, not both. Is there a situation where we would
            # like to show both ?
            if "asiBacktraces" in self.data:
                self.parse_app_specific_backtraces(self.data["asiBacktraces"])
            if "lastExceptionBacktrace" in self.data:
                self.parse_last_exception_backtraces(
                    self.data["lastExceptionBacktrace"]
                )
            self.parse_errors(self.data)
            thread = self.crashlog.threads[self.crashlog.crashed_thread_idx]
            reason = self.parse_crash_reason(self.data["exception"])
            if thread.reason:
                thread.reason = "{} {}".format(thread.reason, reason)
            else:
                thread.reason = reason
        except (KeyError, ValueError, TypeError) as e:
            raise CrashLogParseException(
                "Failed to parse JSON crashlog: {}: {}".format(type(e).__name__, e)
            )

        return self.crashlog

    def get_used_image(self, idx):
        return self.data["usedImages"][idx]

    def parse_process_info(self, json_data):
        self.crashlog.process_id = json_data["pid"]
        self.crashlog.process_identifier = json_data["procName"]
        if "procPath" in json_data:
            self.crashlog.process_path = json_data["procPath"]

    def parse_crash_reason(self, json_exception):
        self.crashlog.exception = json_exception
        exception_type = json_exception["type"]
        exception_signal = " "
        if "signal" in json_exception:
            exception_signal += "({})".format(json_exception["signal"])

        if "codes" in json_exception:
            exception_extra = " ({})".format(json_exception["codes"])
        elif "subtype" in json_exception:
            exception_extra = " ({})".format(json_exception["subtype"])
        else:
            exception_extra = ""
        return "{}{}{}".format(exception_type, exception_signal, exception_extra)

    def parse_images(self, json_images):
        for json_image in json_images:
            img_uuid = uuid.UUID(json_image["uuid"])
            low = int(json_image["base"])
            high = low + int(json_image["size"]) if "size" in json_image else low
            name = json_image["name"] if "name" in json_image else ""
            path = json_image["path"] if "path" in json_image else ""
            version = ""
            darwin_image = self.crashlog.DarwinImage(
                low, high, name, version, img_uuid, path, self.options.verbose
            )
            if "arch" in json_image:
                darwin_image.arch = json_image["arch"]
                if path == self.crashlog.process_path:
                    self.crashlog.process_arch = darwin_image.arch
            self.crashlog.images.append(darwin_image)

    def parse_main_image(self, json_data):
        if "procName" in json_data:
            proc_name = json_data["procName"]
            self.crashlog.set_main_image(proc_name)

    def parse_frames(self, thread, json_frames):
        idx = 0
        for json_frame in json_frames:
            image_id = int(json_frame["imageIndex"])
            json_image = self.get_used_image(image_id)
            ident = json_image["name"] if "name" in json_image else ""
            thread.add_ident(ident)
            if ident not in self.crashlog.idents:
                self.crashlog.idents.append(ident)

            inlined = "inline" in json_frame and bool(json_frame["inline"])
            frame_offset = int(json_frame["imageOffset"])
            image_addr = self.get_used_image(image_id)["base"]
            pc = image_addr + frame_offset

            if "symbol" in json_frame:
                symbol = json_frame["symbol"]
                location = 0
                if "symbolLocation" in json_frame and json_frame["symbolLocation"]:
                    location = int(json_frame["symbolLocation"])
                image = self.crashlog.images[image_id]
                image.symbols[symbol] = {
                    "name": symbol,
                    "type": "code",
                    "address": frame_offset - location,
                }

            thread.frames.append(self.crashlog.Frame(idx, pc, frame_offset, inlined))

            # on arm64 systems, if it jump through a null function pointer,
            # we end up at address 0 and the crash reporter unwinder
            # misses the frame that actually faulted.
            # But $lr can tell us where the last BL/BLR instruction used
            # was at, so insert that address as the caller stack frame.
            if idx == 0 and pc == 0 and "lr" in thread.registers:
                pc = thread.registers["lr"]
                for image in self.data["usedImages"]:
                    text_lo = image["base"]
                    text_hi = text_lo + image["size"]
                    if text_lo <= pc < text_hi:
                        idx += 1
                        frame_offset = pc - text_lo
                        thread.frames.append(self.crashlog.Frame(idx, pc, frame_offset))
                        break

            idx += 1

    def parse_threads(self, json_threads):
        idx = 0
        for json_thread in json_threads:
            thread = self.crashlog.Thread(idx, False, self.crashlog.process_arch)
            if "name" in json_thread:
                thread.name = json_thread["name"]
                thread.reason = json_thread["name"]
            if "id" in json_thread:
                thread.id = int(json_thread["id"])
            if json_thread.get("triggered", False):
                self.crashlog.crashed_thread_idx = idx
                thread.crashed = True
            if "threadState" in json_thread:
                thread.registers = self.parse_thread_registers(
                    json_thread["threadState"]
                )
            if "queue" in json_thread:
                thread.queue = json_thread.get("queue")
            self.parse_frames(thread, json_thread.get("frames", []))
            self.crashlog.threads.append(thread)
            idx += 1

    def parse_asi_backtrace(self, thread, bt):
        for line in bt.split("\n"):
            frame_match = TextCrashLogParser.frame_regex.search(line)
            if not frame_match:
                print("error: can't parse application specific backtrace.")
                return False

            frame_id = (
                frame_img_name
            ) = (
                frame_addr
            ) = (
                frame_symbol
            ) = frame_offset = frame_file = frame_line = frame_column = None

            if len(frame_match.groups()) == 4:
                # Get the image UUID from the frame image name.
                frame_id, frame_img_name, frame_addr, _ = frame_match.groups()
            elif len(frame_match.groups()) == 6:
                (
                    frame_id,
                    frame_img_name,
                    frame_addr,
                    frame_symbol,
                    frame_offset,
                    _,
                ) = frame_match.groups()
            elif len(frame_match.groups()) == 8:
                (
                    frame_id,
                    frame_img_name,
                    frame_addr,
                    frame_symbol,
                    frame_offset,
                    frame_file,
                    frame_line,
                    _,
                ) = frame_match.groups()
            elif len(frame_match.groups()) == 9:
                (
                    frame_id,
                    frame_img_name,
                    frame_addr,
                    frame_symbol,
                    frame_offset,
                    frame_file,
                    frame_line,
                    frame_column,
                    _,
                ) = frame_match.groups()

            inlined = frame_match.group("inlined") is not None

            thread.add_ident(frame_img_name)
            if frame_img_name not in self.crashlog.idents:
                self.crashlog.idents.append(frame_img_name)

            description = ""
            if frame_img_name and frame_addr and frame_symbol:
                description = frame_symbol
                frame_offset_value = 0
                if frame_offset:
                    description += " + " + frame_offset
                    frame_offset_value = int(frame_offset, 0)
                for image in self.crashlog.images:
                    if image.identifier == frame_img_name:
                        image.symbols[frame_symbol] = {
                            "name": frame_symbol,
                            "type": "code",
                            "address": int(frame_addr, 0) - frame_offset_value,
                        }

            thread.frames.append(
                self.crashlog.Frame(
                    int(frame_id), int(frame_addr, 0), description, inlined
                )
            )

        return True

    def parse_app_specific_backtraces(self, json_app_specific_bts):
        thread = self.crashlog.Thread(
            len(self.crashlog.threads), True, self.crashlog.process_arch
        )
        thread.name = "Application Specific Backtrace"
        if self.parse_asi_backtrace(thread, json_app_specific_bts[0]):
            self.crashlog.threads.append(thread)
        else:
            print("error: Couldn't parse Application Specific Backtrace.")

    def parse_last_exception_backtraces(self, json_last_exc_bts):
        thread = self.crashlog.Thread(
            len(self.crashlog.threads), True, self.crashlog.process_arch
        )
        thread.name = "Last Exception Backtrace"
        self.parse_frames(thread, json_last_exc_bts)
        self.crashlog.threads.append(thread)

    def parse_thread_registers(self, json_thread_state, prefix=None):
        registers = dict()
        for key, state in json_thread_state.items():
            if key == "rosetta":
                registers.update(self.parse_thread_registers(state))
                continue
            if key == "x":
                gpr_dict = {str(idx): reg for idx, reg in enumerate(state)}
                registers.update(self.parse_thread_registers(gpr_dict, key))
                continue
            if key == "flavor":
                if not self.crashlog.process_arch:
                    if state == "ARM_THREAD_STATE64":
                        self.crashlog.process_arch = "arm64"
                    elif state == "X86_THREAD_STATE":
                        self.crashlog.process_arch = "x86_64"
                continue
            try:
                value = int(state["value"])
                registers["{}{}".format(prefix or "", key)] = value
            except (KeyError, ValueError, TypeError):
                pass
        return registers

    def parse_errors(self, json_data):
        if "reportNotes" in json_data:
            self.crashlog.errors = json_data["reportNotes"]


class TextCrashLogParser(CrashLogParser):
    parent_process_regex = re.compile(r"^Parent Process:\s*(.*)\[(\d+)\]")
    thread_state_regex = re.compile(r"^Thread (\d+ crashed with|State)")
    thread_instrs_regex = re.compile(r"^Thread \d+ instruction stream")
    thread_regex = re.compile(r"^Thread (\d+).*")
    app_backtrace_regex = re.compile(r"^Application Specific Backtrace (\d+).*")

    class VersionRegex:
        version = r"\(.+\)|(?:arm|x86_)[0-9a-z]+"

    class FrameRegex(VersionRegex):
        @classmethod
        def get(cls):
            index = r"^(\d+)\s+"
            img_name = r"(.+?)\s+"
            version = r"(?:" + super().version + r"\s+)?"
            address = r"(0x[0-9a-fA-F]{4,})"  # 4 digits or more

            symbol = r"""
                        (?:
                            [ ]+
                            (?P<symbol>.+)
                            (?:
                                [ ]\+[ ]
                                (?P<symbol_offset>\d+)
                            )
                            (?:
                                [ ]\(
                                (?P<file_name>[^:]+):(?P<line_number>\d+)
                                (?:
                                    :(?P<column_num>\d+)
                                )?
                            )?
                        )?
                       """

            inlined = r"(?:\s+(?P<inlined>\[inlined\]))?"

            return re.compile(
                index + img_name + version + address + symbol + inlined,
                flags=re.VERBOSE,
            )

    frame_regex = FrameRegex.get()
    null_frame_regex = re.compile(r"^\d+\s+\?\?\?\s+0{4,} +")
    image_regex_uuid = re.compile(
        r"(0x[0-9a-fA-F]+)"  # img_lo
        r"\s+-\s+"  #   -
        r"(0x[0-9a-fA-F]+)\s+"  # img_hi
        r"[+]?(.+?)\s+"  # img_name
        r"(?:(" + VersionRegex.version + r")\s+)?"  # img_version
        r"(?:<([-0-9a-fA-F]+)>\s+)?"  # img_uuid
        r"(\?+|/.*)"  # img_path
    )
    exception_type_regex = re.compile(
        r"^Exception Type:\s+(EXC_[A-Z_]+)(?:\s+\((.*)\))?"
    )
    exception_codes_regex = re.compile(
        r"^Exception Codes:\s+(0x[0-9a-fA-F]+),\s*(0x[0-9a-fA-F]+)"
    )
    exception_extra_regex = re.compile(r"^Exception\s+.*:\s+(.*)")

    class CrashLogParseMode:
        NORMAL = 0
        THREAD = 1
        IMAGES = 2
        THREGS = 3
        SYSTEM = 4
        INSTRS = 5

    def __init__(self, debugger, path, options):
        super().__init__(debugger, path, options)
        self.thread = None
        self.app_specific_backtrace = False
        self.parse_mode = self.CrashLogParseMode.NORMAL
        self.parsers = {
            self.CrashLogParseMode.NORMAL: self.parse_normal,
            self.CrashLogParseMode.THREAD: self.parse_thread,
            self.CrashLogParseMode.IMAGES: self.parse_images,
            self.CrashLogParseMode.THREGS: self.parse_thread_registers,
            self.CrashLogParseMode.SYSTEM: self.parse_system,
            self.CrashLogParseMode.INSTRS: self.parse_instructions,
        }
        self.symbols = {}

    def parse(self):
        with open(self.path, "r", encoding="utf-8") as f:
            lines = f.read().splitlines()

        idx = 0
        lines_count = len(lines)
        while True:
            if idx >= lines_count:
                break

            line = lines[idx]
            line_len = len(line)

            if line_len == 0:
                if self.thread:
                    if self.parse_mode == self.CrashLogParseMode.THREAD:
                        if self.thread.index == self.crashlog.crashed_thread_idx:
                            self.thread.reason = ""
                            if hasattr(self.crashlog, "thread_exception"):
                                self.thread.reason += self.crashlog.thread_exception
                            if hasattr(self.crashlog, "thread_exception_data"):
                                self.thread.reason += (
                                    " (%s)" % self.crashlog.thread_exception_data
                                )
                            self.thread.crashed = True
                        if self.app_specific_backtrace:
                            self.crashlog.backtraces.append(self.thread)
                        else:
                            self.crashlog.threads.append(self.thread)
                    self.thread = None

                empty_lines = 1
                while (
                    idx + empty_lines < lines_count
                    and len(lines[idx + empty_lines]) == 0
                ):
                    empty_lines = empty_lines + 1

                if (
                    empty_lines == 1
                    and idx + empty_lines < lines_count - 1
                    and self.parse_mode != self.CrashLogParseMode.NORMAL
                ):
                    # check if next line can be parsed with the current parse mode
                    next_line_idx = idx + empty_lines
                    if self.parsers[self.parse_mode](lines[next_line_idx]):
                        # If that suceeded, skip the empty line and the next line.
                        idx = next_line_idx + 1
                        continue
                self.parse_mode = self.CrashLogParseMode.NORMAL

            self.parsers[self.parse_mode](line)

            idx = idx + 1

        return self.crashlog

    def parse_exception(self, line):
        if not line.startswith("Exception"):
            return False
        if line.startswith("Exception Type:"):
            self.crashlog.thread_exception = line[15:].strip()
            exception_type_match = self.exception_type_regex.search(line)
            if exception_type_match:
                exc_type, exc_signal = exception_type_match.groups()
                self.crashlog.exception["type"] = exc_type
                if exc_signal:
                    self.crashlog.exception["signal"] = exc_signal
        elif line.startswith("Exception Subtype:"):
            self.crashlog.thread_exception_subtype = line[18:].strip()
            if "type" in self.crashlog.exception:
                self.crashlog.exception[
                    "subtype"
                ] = self.crashlog.thread_exception_subtype
        elif line.startswith("Exception Codes:"):
            self.crashlog.thread_exception_data = line[16:].strip()
            if "type" not in self.crashlog.exception:
                return False
            exception_codes_match = self.exception_codes_regex.search(line)
            if exception_codes_match:
                self.crashlog.exception["codes"] = self.crashlog.thread_exception_data
                code, subcode = exception_codes_match.groups()
                self.crashlog.exception["rawCodes"] = [
                    int(code, base=16),
                    int(subcode, base=16),
                ]
        else:
            if "type" not in self.crashlog.exception:
                return False
            exception_extra_match = self.exception_extra_regex.search(line)
            if exception_extra_match:
                self.crashlog.exception["message"] = exception_extra_match.group(1)
        return True

    def parse_normal(self, line):
        if line.startswith("Process:"):
            (self.crashlog.process_name, pid_with_brackets) = (
                line[8:].strip().split(" [")
            )
            self.crashlog.process_id = pid_with_brackets.strip("[]")
        elif line.startswith("Path:"):
            self.crashlog.process_path = line[5:].strip()
        elif line.startswith("Identifier:"):
            self.crashlog.process_identifier = line[11:].strip()
        elif line.startswith("Version:"):
            version_string = line[8:].strip()
            matched_pair = re.search(r"(.+)\((.+)\)", version_string)
            if matched_pair:
                self.crashlog.process_version = matched_pair.group(1)
                self.crashlog.process_compatability_version = matched_pair.group(2)
            else:
                self.crashlog.process = version_string
                self.crashlog.process_compatability_version = version_string
        elif line.startswith("Code Type:"):
            if "ARM-64" in line:
                self.crashlog.process_arch = "arm64"
            elif "X86-64" in line:
                self.crashlog.process_arch = "x86_64"
        elif self.parent_process_regex.search(line):
            parent_process_match = self.parent_process_regex.search(line)
            self.crashlog.parent_process_name = parent_process_match.group(1)
            self.crashlog.parent_process_id = parent_process_match.group(2)
        elif line.startswith("Exception"):
            self.parse_exception(line)
            return
        elif line.startswith("Crashed Thread:"):
            self.crashlog.crashed_thread_idx = int(line[15:].strip().split()[0])
            return
        elif line.startswith("Triggered by Thread:"):  # iOS
            # Possible formats:
            # Triggered by Thread: 0, Dispatch Queue: com.apple.main-thread
            # Triggered by Thread: 1

            triggered = line[20:].strip().split()[0]

            # Strip the possibly trailing comma.
            triggered = triggered.replace(",", "")

            self.crashlog.crashed_thread_idx = int(triggered)
            return
        elif line.startswith("Report Version:"):
            self.crashlog.version = int(line[15:].strip())
            return
        elif line.startswith("System Profile:"):
            self.parse_mode = self.CrashLogParseMode.SYSTEM
            return
        elif (
            line.startswith("Interval Since Last Report:")
            or line.startswith("Crashes Since Last Report:")
            or line.startswith("Per-App Interval Since Last Report:")
            or line.startswith("Per-App Crashes Since Last Report:")
            or line.startswith("Sleep/Wake UUID:")
            or line.startswith("Anonymous UUID:")
        ):
            # ignore these
            return
        elif line.startswith("Thread"):
            thread_state_match = self.thread_state_regex.search(line)
            if thread_state_match:
                self.app_specific_backtrace = False
                thread_state_match = self.thread_regex.search(line)
                if thread_state_match:
                    thread_idx = int(thread_state_match.group(1))
                else:
                    thread_idx = self.crashlog.crashed_thread_idx
                self.parse_mode = self.CrashLogParseMode.THREGS
                self.thread = self.crashlog.threads[thread_idx]
                return
            thread_insts_match = self.thread_instrs_regex.search(line)
            if thread_insts_match:
                self.parse_mode = self.CrashLogParseMode.INSTRS
                return
            thread_match = self.thread_regex.search(line)
            if thread_match:
                self.app_specific_backtrace = False
                self.parse_mode = self.CrashLogParseMode.THREAD
                thread_idx = int(thread_match.group(1))
                self.thread = self.crashlog.Thread(
                    thread_idx, False, self.crashlog.process_arch
                )
                return
            return
        elif line.startswith("Binary Images:"):
            self.parse_mode = self.CrashLogParseMode.IMAGES
            return
        elif line.startswith("Application Specific Backtrace"):
            app_backtrace_match = self.app_backtrace_regex.search(line)
            if app_backtrace_match:
                self.parse_mode = self.CrashLogParseMode.THREAD
                self.app_specific_backtrace = True
                idx = int(app_backtrace_match.group(1))
                self.thread = self.crashlog.Thread(
                    idx, True, self.crashlog.process_arch
                )
                self.thread.name = "Application Specific Backtrace"
        elif line.startswith("Last Exception Backtrace:"):  # iOS
            self.parse_mode = self.CrashLogParseMode.THREAD
            self.app_specific_backtrace = True
            idx = 1
            self.thread = self.crashlog.Thread(idx, True, self.crashlog.process_arch)
            self.thread.name = "Last Exception Backtrace"
        self.crashlog.info_lines.append(line.strip())

    def parse_thread(self, line):
        if line.startswith("Thread"):
            return False
        if self.null_frame_regex.search(line):
            print('warning: thread parser ignored null-frame: "%s"' % line)
            return False
        frame_match = self.frame_regex.search(line)
        if not frame_match:
            print('error: frame regex failed for line: "%s"' % line)
            return False

        frame_id = (
            frame_img_name
        ) = (
            frame_addr
        ) = frame_symbol = frame_offset = frame_file = frame_line = frame_column = None

        if len(frame_match.groups()) == 4:
            # Get the image UUID from the frame image name.
            frame_id, frame_img_name, frame_addr, _ = frame_match.groups()
        elif len(frame_match.groups()) == 6:
            (
                frame_id,
                frame_img_name,
                frame_addr,
                frame_symbol,
                frame_offset,
                _,
            ) = frame_match.groups()
        elif len(frame_match.groups()) == 8:
            (
                frame_id,
                frame_img_name,
                frame_addr,
                frame_symbol,
                frame_offset,
                frame_file,
                frame_line,
                _,
            ) = frame_match.groups()
        elif len(frame_match.groups()) == 9:
            (
                frame_id,
                frame_img_name,
                frame_addr,
                frame_symbol,
                frame_offset,
                frame_file,
                frame_line,
                frame_column,
                _,
            ) = frame_match.groups()

        inlined = frame_match.group("inlined") is not None

        self.thread.add_ident(frame_img_name)
        if frame_img_name not in self.crashlog.idents:
            self.crashlog.idents.append(frame_img_name)

        description = ""
        # Since images are parsed after threads, we need to build a
        # map for every image with a list of all the symbols and addresses
        if frame_img_name and frame_addr and frame_symbol:
            description = frame_symbol
            frame_offset_value = 0
            if frame_offset:
                description += " + " + frame_offset
                frame_offset_value = int(frame_offset, 0)
            if frame_img_name not in self.symbols:
                self.symbols[frame_img_name] = list()
            self.symbols[frame_img_name].append(
                {
                    "name": frame_symbol,
                    "address": int(frame_addr, 0) - frame_offset_value,
                }
            )

        self.thread.frames.append(
            self.crashlog.Frame(int(frame_id), int(frame_addr, 0), description, inlined)
        )

        return True

    def parse_images(self, line):
        image_match = self.image_regex_uuid.search(line)
        if image_match:
            (
                img_lo,
                img_hi,
                img_name,
                img_version,
                img_uuid,
                img_path,
            ) = image_match.groups()

            image = self.crashlog.DarwinImage(
                int(img_lo, 0),
                int(img_hi, 0),
                img_name.strip(),
                img_version.strip() if img_version else "",
                uuid.UUID(img_uuid),
                img_path,
                self.options.verbose,
            )
            unqualified_img_name = os.path.basename(img_path)
            if unqualified_img_name in self.symbols:
                for symbol in self.symbols[unqualified_img_name]:
                    image.symbols[symbol["name"]] = {
                        "name": symbol["name"],
                        "type": "code",
                        # NOTE: "address" is actually the symbol image offset
                        "address": symbol["address"] - int(img_lo, 0),
                    }

            self.crashlog.images.append(image)
            return True
        else:
            if self.options.debug:
                print("error: image regex failed for: %s" % line)
            return False

    def parse_thread_registers(self, line):
        # "r12: 0x00007fff6b5939c8  r13: 0x0000000007000006  r14: 0x0000000000002a03  r15: 0x0000000000000c00"
        reg_values = re.findall("([a-z0-9]+): (0x[0-9a-f]+)", line, re.I)
        for reg, value in reg_values:
            self.thread.registers[reg] = int(value, 16)
        return len(reg_values) != 0

    def parse_system(self, line):
        self.crashlog.system_profile.append(line)
        return True

    def parse_instructions(self, line):
        pass


def save_crashlog(debugger, command, exe_ctx, result, dict):
    usage = "save_crashlog [options] <output-path>"
    description = """Export the state of current target into a crashlog file"""
    parser = argparse.ArgumentParser(
        description=description,
        prog="save_crashlog",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )
    parser.add_argument(
        "output",
        metavar="output-file",
        type=argparse.FileType("w", encoding="utf-8"),
        nargs=1,
    )
    parser.add_argument(
        "-v",
        "--verbose",
        action="store_true",
        dest="verbose",
        help="display verbose debug info",
        default=False,
    )
    try:
        options = parser.parse_args(shlex.split(command))
    except Exception as e:
        result.SetError(str(e))
        return
    target = exe_ctx.target
    if target:
        out_file = options.output[0]
        identifier = target.executable.basename
        process = exe_ctx.process
        if process:
            pid = process.id
            if pid != lldb.LLDB_INVALID_PROCESS_ID:
                out_file.write("Process:         %s [%u]\n" % (identifier, pid))
        out_file.write("Path:            %s\n" % (target.executable.fullpath))
        out_file.write("Identifier:      %s\n" % (identifier))
        out_file.write(
            "\nDate/Time:       %s\n"
            % (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        )
        out_file.write(
            "OS Version:      Mac OS X %s (%s)\n"
            % (
                platform.mac_ver()[0],
                subprocess.check_output("sysctl -n kern.osversion", shell=True).decode(
                    "utf-8"
                ),
            )
        )
        out_file.write("Report Version:  9\n")
        for thread_idx in range(process.num_threads):
            thread = process.thread[thread_idx]
            out_file.write("\nThread %u:\n" % (thread_idx))
            for frame_idx, frame in enumerate(thread.frames):
                frame_pc = frame.pc
                frame_offset = 0
                if frame.function:
                    block = frame.GetFrameBlock()
                    block_range = block.range[frame.addr]
                    if block_range:
                        block_start_addr = block_range[0]
                        frame_offset = frame_pc - block_start_addr.GetLoadAddress(
                            target
                        )
                    else:
                        frame_offset = frame_pc - frame.function.addr.GetLoadAddress(
                            target
                        )
                elif frame.symbol:
                    frame_offset = frame_pc - frame.symbol.addr.GetLoadAddress(target)
                out_file.write(
                    "%-3u %-32s 0x%16.16x %s"
                    % (frame_idx, frame.module.file.basename, frame_pc, frame.name)
                )
                if frame_offset > 0:
                    out_file.write(" + %u" % (frame_offset))
                line_entry = frame.line_entry
                if line_entry:
                    if options.verbose:
                        # This will output the fullpath + line + column
                        out_file.write(" %s" % (line_entry))
                    else:
                        out_file.write(
                            " %s:%u" % (line_entry.file.basename, line_entry.line)
                        )
                        column = line_entry.column
                        if column:
                            out_file.write(":%u" % (column))
                out_file.write("\n")

        out_file.write("\nBinary Images:\n")
        for module in target.modules:
            text_segment = module.section["__TEXT"]
            if text_segment:
                text_segment_load_addr = text_segment.GetLoadAddress(target)
                if text_segment_load_addr != lldb.LLDB_INVALID_ADDRESS:
                    text_segment_end_load_addr = (
                        text_segment_load_addr + text_segment.size
                    )
                    identifier = module.file.basename
                    module_version = "???"
                    module_version_array = module.GetVersion()
                    if module_version_array:
                        module_version = ".".join(map(str, module_version_array))
                    out_file.write(
                        "    0x%16.16x - 0x%16.16x  %s (%s - ???) <%s> %s\n"
                        % (
                            text_segment_load_addr,
                            text_segment_end_load_addr,
                            identifier,
                            module_version,
                            module.GetUUIDString(),
                            module.file.fullpath,
                        )
                    )
        out_file.close()
    else:
        result.SetError("invalid target")


class Symbolicate:
    def __init__(self, debugger, internal_dict):
        pass

    def __call__(self, debugger, command, exe_ctx, result):
        SymbolicateCrashLogs(debugger, shlex.split(command), result, True)

    def get_short_help(self):
        return "Symbolicate one or more darwin crash log files."

    def get_long_help(self):
        arg_parser = CrashLogOptionParser()
        return arg_parser.format_help()


def SymbolicateCrashLog(crash_log, options):
    if options.debug:
        crash_log.dump()
    if not crash_log.images:
        print("error: no images in crash log")
        return

    if options.dump_image_list:
        print("Binary Images:")
        for image in crash_log.images:
            if options.verbose:
                print(image.debug_dump())
            else:
                print(image)

    target = crash_log.create_target()
    if not target:
        return

    crash_log.load_images(options)

    if crash_log.backtraces:
        for thread in crash_log.backtraces:
            thread.dump_symbolicated(crash_log, options)
            print()

    for thread in crash_log.threads:
        if options.crashed_only and not (
            thread.crashed or thread.app_specific_backtrace
        ):
            continue
        thread.dump_symbolicated(crash_log, options)
        print()

    if crash_log.errors:
        print("Errors:")
        for error in crash_log.errors:
            print(error)


def load_crashlog_in_scripted_process(debugger, crashlog_path, options, result):
    crashlog = CrashLogParser.create(debugger, crashlog_path, options).parse()

    target = lldb.SBTarget()
    # 1. Try to use the user-provided target
    if options.target_path:
        target = debugger.CreateTarget(options.target_path)
        if not target:
            raise InteractiveCrashLogException(
                "couldn't create target provided by the user (%s)" % options.target_path
            )
        crashlog.target = target

    # 2. If the user didn't provide a target, try to create a target using the symbolicator
    if not target or not target.IsValid():
        target = crashlog.create_target()
    # 3. If that didn't work, create a dummy target
    if target is None or not target.IsValid():
        arch = crashlog.process_arch
        if not arch:
            raise InteractiveCrashLogException(
                "couldn't find the architecture to create the target"
            )
        target = debugger.CreateTargetWithFileAndArch(None, arch)
    # 4. Fail
    if target is None or not target.IsValid():
        raise InteractiveCrashLogException("couldn't create target")

    ci = debugger.GetCommandInterpreter()
    if not ci:
        raise InteractiveCrashLogException("couldn't get command interpreter")

    ci.HandleCommand("script from lldb.macosx import crashlog_scripted_process", result)
    if not result.Succeeded():
        raise InteractiveCrashLogException(
            "couldn't import crashlog scripted process module"
        )

    structured_data = lldb.SBStructuredData()
    structured_data.SetFromJSON(
        json.dumps(
            {
                "file_path": crashlog_path,
                "load_all_images": options.load_all_images,
                "crashed_only": options.crashed_only,
                "no_parallel_image_loading": options.no_parallel_image_loading,
            }
        )
    )

    crashlog_sd = lldb.SBStructuredData()
    crashlog_sd.SetGenericValue(
        lldb.SBScriptObject(crashlog, lldb.eScriptLanguagePython)
    )
    structured_data.SetValueForKey("crashlog", crashlog_sd)

    launch_info = lldb.SBLaunchInfo(None)
    launch_info.SetProcessPluginName("ScriptedProcess")
    launch_info.SetScriptedProcessClassName(
        "crashlog_scripted_process.CrashLogScriptedProcess"
    )
    launch_info.SetScriptedProcessDictionary(structured_data)

    error = lldb.SBError()
    process = target.Launch(launch_info, error)

    if not process or error.Fail():
        raise InteractiveCrashLogException("couldn't launch Scripted Process", error)

    if not options.skip_status:

        @contextlib.contextmanager
        def synchronous(debugger):
            async_state = debugger.GetAsync()
            debugger.SetAsync(False)
            try:
                yield
            finally:
                debugger.SetAsync(async_state)

        with synchronous(debugger):
            run_options = lldb.SBCommandInterpreterRunOptions()
            run_options.SetStopOnError(True)
            run_options.SetStopOnCrash(True)
            run_options.SetEchoCommands(True)

            commands_stream = lldb.SBStream()
            commands_stream.Print("process status --verbose\n")
            commands_stream.Print("thread backtrace --extended true\n")
            error = debugger.SetInputString(commands_stream.GetData())
            if error.Success():
                debugger.RunCommandInterpreter(True, False, run_options, 0, False, True)


class CrashLogLoadingMode(str, enum.Enum):
    batch = "batch"
    interactive = "interactive"


def CreateSymbolicateCrashLogOptions(command_name, description):
    usage = "crashlog [options] <FILE> [FILE ...]"
    arg_parser = argparse.ArgumentParser(
        description=description,
        prog="crashlog",
        usage=usage,
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )
    arg_parser.add_argument(
        "reports",
        metavar="FILE",
        type=str,
        nargs="*",
        help="crash report(s) to symbolicate",
    )

    arg_parser.add_argument(
        "-m",
        "--mode",
        choices=[mode.value for mode in CrashLogLoadingMode],
        help="change how the symbolicated process and threads are displayed to the user (default: interactive)",
    )
    arg_parser.add_argument(
        "--version",
        "-V",
        dest="version",
        action="store_true",
        help="Show crashlog version",
        default=False,
    )
    arg_parser.add_argument(
        "--verbose",
        "-v",
        action="store_true",
        dest="verbose",
        help="display verbose debug info",
        default=False,
    )
    arg_parser.add_argument(
        "--debug",
        "-g",
        action="store_true",
        dest="debug",
        help="display verbose debug logging",
        default=False,
    )
    arg_parser.add_argument(
        "--load-all",
        "-a",
        action="store_true",
        dest="load_all_images",
        help="load all executable images, not just the images found in the "
        "crashed stack frames, loads stackframes for all the threads in "
        "interactive mode.",
        default=False,
    )
    arg_parser.add_argument(
        "--images",
        action="store_true",
        dest="dump_image_list",
        help="show image list",
        default=False,
    )
    arg_parser.add_argument(
        "--debug-delay",
        type=int,
        dest="debug_delay",
        metavar="NSEC",
        help="pause for NSEC seconds for debugger",
        default=0,
    )
    # NOTE: Requires python 3.9
    # arg_parser.add_argument(
    #     "--crashed-only",
    #     "-c",
    #     action=argparse.BooleanOptionalAction,
    #     dest="crashed_only",
    #     help="only symbolicate the crashed thread",
    #     default=True,
    # )
    arg_parser.add_argument(
        "--crashed-only",
        "-c",
        action="store_true",
        dest="crashed_only",
        help="only symbolicate the crashed thread",
        default=True,
    )
    arg_parser.add_argument(
        "--no-crashed-only",
        action="store_false",
        dest="crashed_only",
        help="in batch mode, symbolicate all threads, not only the crashed one",
        default=False,
    )
    arg_parser.add_argument(
        "--disasm-depth",
        "-d",
        type=int,
        dest="disassemble_depth",
        help="set the depth in stack frames that should be disassembled",
        default=1,
    )
    arg_parser.add_argument(
        "--disasm-all",
        "-D",
        action="store_true",
        dest="disassemble_all_threads",
        help="enabled disassembly of frames on all threads (not just the crashed thread)",
        default=False,
    )
    arg_parser.add_argument(
        "--disasm-before",
        "-B",
        type=int,
        dest="disassemble_before",
        help="the number of instructions to disassemble before the frame PC",
        default=4,
    )
    arg_parser.add_argument(
        "--disasm-after",
        "-A",
        type=int,
        dest="disassemble_after",
        help="the number of instructions to disassemble after the frame PC",
        default=4,
    )
    arg_parser.add_argument(
        "--source-context",
        "-C",
        type=int,
        metavar="NLINES",
        dest="source_context",
        help="show NLINES source lines of source context",
        default=4,
    )
    arg_parser.add_argument(
        "--source-frames",
        type=int,
        metavar="NFRAMES",
        dest="source_frames",
        help="show source for NFRAMES",
        default=4,
    )
    arg_parser.add_argument(
        "--source-all",
        action="store_true",
        dest="source_all",
        help="show source for all threads, not just the crashed thread",
        default=False,
    )
    arg_parser.add_argument(
        "--no-parallel-image-loading",
        dest="no_parallel_image_loading",
        action="store_true",
        help=argparse.SUPPRESS,
        default=False,
    )
    arg_parser.add_argument(
        "--target",
        "-t",
        dest="target_path",
        help="the target binary path that should be used for interactive crashlog (optional)",
        default=None,
    )
    arg_parser.add_argument(
        "--skip-status",
        "-s",
        dest="skip_status",
        action="store_true",
        help="prevent the interactive crashlog to dump the process status and thread backtrace at launch",
        default=False,
    )
    legacy_group = arg_parser.add_mutually_exclusive_group()
    legacy_group.add_argument(
        "-i",
        "--interactive",
        action="store_true",
        help=argparse.SUPPRESS,
    )
    legacy_group.add_argument(
        "-b",
        "--batch",
        action="store_true",
        help=argparse.SUPPRESS,
    )

    return arg_parser


def CrashLogOptionParser():
    description = """Symbolicate one or more darwin crash log files to provide source file and line information,
inlined stack frames back to the concrete functions, and disassemble the location of the crash
for the first frame of the crashed thread.
If this script is imported into the LLDB command interpreter, a "crashlog" command will be added to the interpreter
for use at the LLDB command line. After a crash log has been parsed and symbolicated, a target will have been
created that has all of the shared libraries loaded at the load addresses found in the crash log file. This allows
you to explore the program as if it were stopped at the locations described in the crash log and functions can
be disassembled and lookups can be performed using the addresses found in the crash log."""
    return CreateSymbolicateCrashLogOptions("crashlog", description)


def SymbolicateCrashLogs(debugger, command_args, result, is_command):
    arg_parser = CrashLogOptionParser()

    if not len(command_args):
        arg_parser.print_help()
        return

    try:
        options = arg_parser.parse_args(command_args)
    except Exception as e:
        result.SetError(str(e))
        return

    # To avoid breaking existing users, we should keep supporting legacy flags
    # even if we don't use them / advertise them anymore.
    if not options.mode:
        if options.batch:
            options.mode = CrashLogLoadingMode.batch
        else:
            options.mode = CrashLogLoadingMode.interactive

    if options.mode != CrashLogLoadingMode.interactive and (
        options.target_path or options.skip_status
    ):
        print(
            "Target path (-t) and skipping process status (-s) options can only used in interactive mode (-m=interactive)."
        )
        print("Aborting symbolication.")
        arg_parser.print_help()
        return

    if options.version:
        print(debugger.GetVersionString())
        return

    if options.debug:
        print("command_args = %s" % command_args)
        print("options", options)
        print("args", options.reports)

    # Interactive mode requires running the crashlog command from inside lldb.
    if options.mode == CrashLogLoadingMode.interactive and not is_command:
        lldb_exec = (
            subprocess.check_output(["/usr/bin/xcrun", "-f", "lldb"])
            .decode("utf-8")
            .strip()
        )
        sys.exit(
            os.execv(
                lldb_exec,
                [
                    lldb_exec,
                    "-o",
                    "command script import lldb.macosx",
                    "-o",
                    "crashlog {}".format(shlex.join(command_args)),
                ],
            )
        )

    if "NO_PARALLEL_IMG_LOADING" in os.environ:
        options.no_parallel_image_loading = True

    if options.version:
        print(debugger.GetVersionString())
        return

    if options.debug_delay > 0:
        print("Waiting %u seconds for debugger to attach..." % options.debug_delay)
        time.sleep(options.debug_delay)
    error = lldb.SBError()

    def should_run_in_interactive_mode(options, ci):
        if options.mode == CrashLogLoadingMode.batch:
            return False
        elif options.mode == CrashLogLoadingMode.interactive or (
            ci and ci.IsInteractive()
        ):
            return True
        else:
            return sys.stdout.isatty()

    ci = debugger.GetCommandInterpreter()

    if options.reports:
        for crashlog_file in options.reports:
            crashlog_path = os.path.normpath(os.path.expanduser(crashlog_file))
            if not os.path.exists(crashlog_path):
                raise FileNotFoundError(
                    "crashlog file %s does not exist" % crashlog_path
                )
            if should_run_in_interactive_mode(options, ci):
                try:
                    load_crashlog_in_scripted_process(
                        debugger, crashlog_path, options, result
                    )
                except InteractiveCrashLogException as e:
                    result.SetError(str(e))
            else:
                crash_log = CrashLogParser.create(
                    debugger, crashlog_path, options
                ).parse()
                SymbolicateCrashLog(crash_log, options)


if __name__ == "__main__":
    # Create a new debugger instance
    debugger = lldb.SBDebugger.Create()
    result = lldb.SBCommandReturnObject()
    SymbolicateCrashLogs(debugger, sys.argv[1:], result, False)
    lldb.SBDebugger.Destroy(debugger)


def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand(
        "command script add -o -c lldb.macosx.crashlog.Symbolicate -C disk-file crashlog"
    )
    debugger.HandleCommand(
        "command script add -o -f lldb.macosx.crashlog.save_crashlog -C disk-file save_crashlog"
    )
    print(
        '"crashlog" and "save_crashlog" commands have been installed, use '
        'the "--help" options on these commands for detailed help.'
    )
