#!/usr/bin/env python3

# ----------------------------------------------------------------------
# Be sure to add the python path that points to the LLDB shared library.
# On MacOSX csh, tcsh:
#   setenv PYTHONPATH /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python
# On MacOSX sh, bash:
#   export PYTHONPATH=/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python
# ----------------------------------------------------------------------

import optparse
import os
import platform
import sys
import subprocess

# ----------------------------------------------------------------------
# Code that auto imports LLDB
# ----------------------------------------------------------------------
try:
    # Just try for LLDB in case PYTHONPATH is already correctly setup
    import lldb
except ImportError:
    lldb_python_dirs = list()
    # lldb is not in the PYTHONPATH, try some defaults for the current platform
    platform_system = platform.system()
    if platform_system == "Darwin":
        # On Darwin, try the currently selected Xcode directory
        xcode_dir = subprocess.check_output("xcode-select --print-path", shell=True)
        if xcode_dir:
            lldb_python_dirs.append(
                os.path.realpath(
                    xcode_dir + "/../SharedFrameworks/LLDB.framework/Resources/Python"
                )
            )
            lldb_python_dirs.append(
                xcode_dir + "/Library/PrivateFrameworks/LLDB.framework/Resources/Python"
            )
        lldb_python_dirs.append(
            "/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python"
        )
    success = False
    for lldb_python_dir in lldb_python_dirs:
        if os.path.exists(lldb_python_dir):
            if not (sys.path.__contains__(lldb_python_dir)):
                sys.path.append(lldb_python_dir)
                try:
                    import lldb
                except ImportError:
                    pass
                else:
                    print('imported lldb from: "%s"' % (lldb_python_dir))
                    success = True
                    break
    if not success:
        print(
            "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
        )
        sys.exit(1)


def print_threads(process, options):
    if options.show_threads:
        for thread in process:
            print("%s %s" % (thread, thread.GetFrameAtIndex(0)))


def run_commands(command_interpreter, commands):
    return_obj = lldb.SBCommandReturnObject()
    for command in commands:
        command_interpreter.HandleCommand(command, return_obj)
        if return_obj.Succeeded():
            print(return_obj.GetOutput())
        else:
            print(return_obj)
            if options.stop_on_error:
                break


def main(argv):
    description = """Debugs a program using the LLDB python API and uses asynchronous broadcast events to watch for process state changes."""
    epilog = """Examples:

#----------------------------------------------------------------------
# Run "/bin/ls" with the arguments "-lAF /tmp/", and set a breakpoint
# at "malloc" and backtrace and read all registers each time we stop
#----------------------------------------------------------------------
% ./process_events.py --breakpoint malloc --stop-command bt --stop-command 'register read' -- /bin/ls -lAF /tmp/

"""
    optparse.OptionParser.format_epilog = lambda self, formatter: self.epilog
    parser = optparse.OptionParser(
        description=description,
        prog="process_events",
        usage="usage: process_events [options] program [arg1 arg2]",
        epilog=epilog,
    )
    parser.add_option(
        "-v",
        "--verbose",
        action="store_true",
        dest="verbose",
        help="Enable verbose logging.",
        default=False,
    )
    parser.add_option(
        "-b",
        "--breakpoint",
        action="append",
        type="string",
        metavar="BPEXPR",
        dest="breakpoints",
        help='Breakpoint commands to create after the target has been created, the values will be sent to the "_regexp-break" command which supports breakpoints by name, file:line, and address.',
    )
    parser.add_option(
        "-a",
        "--arch",
        type="string",
        dest="arch",
        help="The architecture to use when creating the debug target.",
        default=None,
    )
    parser.add_option(
        "--platform",
        type="string",
        metavar="platform",
        dest="platform",
        help='Specify the platform to use when creating the debug target. Valid values include "localhost", "darwin-kernel", "ios-simulator", "remote-freebsd", "remote-macosx", "remote-ios", "remote-linux".',
        default=None,
    )
    parser.add_option(
        "-l",
        "--launch-command",
        action="append",
        type="string",
        metavar="CMD",
        dest="launch_commands",
        help="LLDB command interpreter commands to run once after the process has launched. This option can be specified more than once.",
        default=[],
    )
    parser.add_option(
        "-s",
        "--stop-command",
        action="append",
        type="string",
        metavar="CMD",
        dest="stop_commands",
        help="LLDB command interpreter commands to run each time the process stops. This option can be specified more than once.",
        default=[],
    )
    parser.add_option(
        "-c",
        "--crash-command",
        action="append",
        type="string",
        metavar="CMD",
        dest="crash_commands",
        help="LLDB command interpreter commands to run in case the process crashes. This option can be specified more than once.",
        default=[],
    )
    parser.add_option(
        "-x",
        "--exit-command",
        action="append",
        type="string",
        metavar="CMD",
        dest="exit_commands",
        help="LLDB command interpreter commands to run once after the process has exited. This option can be specified more than once.",
        default=[],
    )
    parser.add_option(
        "-T",
        "--no-threads",
        action="store_false",
        dest="show_threads",
        help="Don't show threads when process stops.",
        default=True,
    )
    parser.add_option(
        "--ignore-errors",
        action="store_false",
        dest="stop_on_error",
        help="Don't stop executing LLDB commands if the command returns an error. This applies to all of the LLDB command interpreter commands that get run for launch, stop, crash and exit.",
        default=True,
    )
    parser.add_option(
        "-n",
        "--run-count",
        type="int",
        dest="run_count",
        metavar="N",
        help="How many times to run the process in case the process exits.",
        default=1,
    )
    parser.add_option(
        "-t",
        "--event-timeout",
        type="int",
        dest="event_timeout",
        metavar="SEC",
        help="Specify the timeout in seconds to wait for process state change events.",
        default=lldb.UINT32_MAX,
    )
    parser.add_option(
        "-e",
        "--environment",
        action="append",
        type="string",
        metavar="ENV",
        dest="env_vars",
        help="Environment variables to set in the inferior process when launching a process.",
    )
    parser.add_option(
        "-d",
        "--working-dir",
        type="string",
        metavar="DIR",
        dest="working_dir",
        help="The current working directory when launching a process.",
        default=None,
    )
    parser.add_option(
        "-p",
        "--attach-pid",
        type="int",
        dest="attach_pid",
        metavar="PID",
        help="Specify a process to attach to by process ID.",
        default=-1,
    )
    parser.add_option(
        "-P",
        "--attach-name",
        type="string",
        dest="attach_name",
        metavar="PROCESSNAME",
        help="Specify a process to attach to by name.",
        default=None,
    )
    parser.add_option(
        "-w",
        "--attach-wait",
        action="store_true",
        dest="attach_wait",
        help="Wait for the next process to launch when attaching to a process by name.",
        default=False,
    )
    try:
        (options, args) = parser.parse_args(argv)
    except:
        return

    attach_info = None
    launch_info = None
    exe = None
    if args:
        exe = args.pop(0)
        launch_info = lldb.SBLaunchInfo(args)
        if options.env_vars:
            launch_info.SetEnvironmentEntries(options.env_vars, True)
        if options.working_dir:
            launch_info.SetWorkingDirectory(options.working_dir)
    elif options.attach_pid != -1:
        if options.run_count == 1:
            attach_info = lldb.SBAttachInfo(options.attach_pid)
        else:
            print("error: --run-count can't be used with the --attach-pid option")
            sys.exit(1)
    elif not options.attach_name is None:
        if options.run_count == 1:
            attach_info = lldb.SBAttachInfo(options.attach_name, options.attach_wait)
        else:
            print("error: --run-count can't be used with the --attach-name option")
            sys.exit(1)
    else:
        print(
            "error: a program path for a program to debug and its arguments are required"
        )
        sys.exit(1)

    # Create a new debugger instance
    debugger = lldb.SBDebugger.Create()
    debugger.SetAsync(True)
    command_interpreter = debugger.GetCommandInterpreter()
    # Create a target from a file and arch

    if exe:
        print("Creating a target for '%s'" % exe)
    error = lldb.SBError()
    target = debugger.CreateTarget(exe, options.arch, options.platform, True, error)

    if target:
        # Set any breakpoints that were specified in the args if we are launching. We use the
        # command line command to take advantage of the shorthand breakpoint
        # creation
        if launch_info and options.breakpoints:
            for bp in options.breakpoints:
                debugger.HandleCommand("_regexp-break %s" % (bp))
            run_commands(command_interpreter, ["breakpoint list"])

        for run_idx in range(options.run_count):
            # Launch the process. Since we specified synchronous mode, we won't return
            # from this function until we hit the breakpoint at main
            error = lldb.SBError()

            if launch_info:
                if options.run_count == 1:
                    print('Launching "%s"...' % (exe))
                else:
                    print(
                        'Launching "%s"... (launch %u of %u)'
                        % (exe, run_idx + 1, options.run_count)
                    )

                process = target.Launch(launch_info, error)
            else:
                if options.attach_pid != -1:
                    print("Attaching to process %i..." % (options.attach_pid))
                else:
                    if options.attach_wait:
                        print(
                            'Waiting for next to process named "%s" to launch...'
                            % (options.attach_name)
                        )
                    else:
                        print(
                            'Attaching to existing process named "%s"...'
                            % (options.attach_name)
                        )
                process = target.Attach(attach_info, error)

            # Make sure the launch went ok
            if process and process.GetProcessID() != lldb.LLDB_INVALID_PROCESS_ID:
                pid = process.GetProcessID()
                print("Process is %i" % (pid))
                if attach_info:
                    # continue process if we attached as we won't get an
                    # initial event
                    process.Continue()

                listener = debugger.GetListener()
                # sign up for process state change events
                stop_idx = 0
                done = False
                while not done:
                    event = lldb.SBEvent()
                    if listener.WaitForEvent(options.event_timeout, event):
                        if lldb.SBProcess.EventIsProcessEvent(event):
                            state = lldb.SBProcess.GetStateFromEvent(event)
                            if state == lldb.eStateInvalid:
                                # Not a state event
                                print("process event = %s" % (event))
                            else:
                                print(
                                    "process state changed event: %s"
                                    % (lldb.SBDebugger.StateAsCString(state))
                                )
                                if state == lldb.eStateStopped:
                                    if stop_idx == 0:
                                        if launch_info:
                                            print("process %u launched" % (pid))
                                            run_commands(
                                                command_interpreter, ["breakpoint list"]
                                            )
                                        else:
                                            print("attached to process %u" % (pid))
                                            for m in target.modules:
                                                print(m)
                                            if options.breakpoints:
                                                for bp in options.breakpoints:
                                                    debugger.HandleCommand(
                                                        "_regexp-break %s" % (bp)
                                                    )
                                                run_commands(
                                                    command_interpreter,
                                                    ["breakpoint list"],
                                                )
                                        run_commands(
                                            command_interpreter, options.launch_commands
                                        )
                                    else:
                                        if options.verbose:
                                            print("process %u stopped" % (pid))
                                        run_commands(
                                            command_interpreter, options.stop_commands
                                        )
                                    stop_idx += 1
                                    print_threads(process, options)
                                    print("continuing process %u" % (pid))
                                    process.Continue()
                                elif state == lldb.eStateExited:
                                    exit_desc = process.GetExitDescription()
                                    if exit_desc:
                                        print(
                                            "process %u exited with status %u: %s"
                                            % (pid, process.GetExitStatus(), exit_desc)
                                        )
                                    else:
                                        print(
                                            "process %u exited with status %u"
                                            % (pid, process.GetExitStatus())
                                        )
                                    run_commands(
                                        command_interpreter, options.exit_commands
                                    )
                                    done = True
                                elif state == lldb.eStateCrashed:
                                    print("process %u crashed" % (pid))
                                    print_threads(process, options)
                                    run_commands(
                                        command_interpreter, options.crash_commands
                                    )
                                    done = True
                                elif state == lldb.eStateDetached:
                                    print("process %u detached" % (pid))
                                    done = True
                                elif state == lldb.eStateRunning:
                                    # process is running, don't say anything,
                                    # we will always get one of these after
                                    # resuming
                                    if options.verbose:
                                        print("process %u resumed" % (pid))
                                elif state == lldb.eStateUnloaded:
                                    print(
                                        "process %u unloaded, this shouldn't happen"
                                        % (pid)
                                    )
                                    done = True
                                elif state == lldb.eStateConnected:
                                    print("process connected")
                                elif state == lldb.eStateAttaching:
                                    print("process attaching")
                                elif state == lldb.eStateLaunching:
                                    print("process launching")
                        else:
                            print("event = %s" % (event))
                    else:
                        # timeout waiting for an event
                        print(
                            "no process event for %u seconds, killing the process..."
                            % (options.event_timeout)
                        )
                        done = True
                # Now that we are done dump the stdout and stderr
                process_stdout = process.GetSTDOUT(1024)
                if process_stdout:
                    print("Process STDOUT:\n%s" % (process_stdout))
                    while process_stdout:
                        process_stdout = process.GetSTDOUT(1024)
                        print(process_stdout)
                process_stderr = process.GetSTDERR(1024)
                if process_stderr:
                    print("Process STDERR:\n%s" % (process_stderr))
                    while process_stderr:
                        process_stderr = process.GetSTDERR(1024)
                        print(process_stderr)
                process.Kill()  # kill the process
            else:
                if error:
                    print(error)
                else:
                    if launch_info:
                        print("error: launch failed")
                    else:
                        print("error: attach failed")

    lldb.SBDebugger.Terminate()


if __name__ == "__main__":
    main(sys.argv[1:])
