diff options
Diffstat (limited to 'examples/python/process_events.py')
-rwxr-xr-x | examples/python/process_events.py | 417 |
1 files changed, 0 insertions, 417 deletions
diff --git a/examples/python/process_events.py b/examples/python/process_events.py deleted file mode 100755 index c93020a979f0..000000000000 --- a/examples/python/process_events.py +++ /dev/null @@ -1,417 +0,0 @@ -#!/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 -#---------------------------------------------------------------------- - -import commands -import optparse -import os -import platform -import sys - -#---------------------------------------------------------------------- -# 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 = commands.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:]) |