#!/usr/bin/python

#----------------------------------------------------------------------
# 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
#----------------------------------------------------------------------

from __future__ import print_function

import optparse
import os
import platform
import sys

if sys.version_info.major == 2:
    import commands as subprocess
else:
    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.getoutput("xcode-select --print-path")
        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 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:])
