1515bc8c1Sserge-sans-paille#!/usr/bin/env python 2c769722aSGreg Clayton 3c769722aSGreg Clayton#---------------------------------------------------------------------- 4c769722aSGreg Clayton# Be sure to add the python path that points to the LLDB shared library. 5c769722aSGreg Clayton# On MacOSX csh, tcsh: 6c769722aSGreg Clayton# setenv PYTHONPATH /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python 7c769722aSGreg Clayton# On MacOSX sh, bash: 8c769722aSGreg Clayton# export PYTHONPATH=/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python 9c769722aSGreg Clayton#---------------------------------------------------------------------- 10c769722aSGreg Clayton 11525cd59fSSerge Gueltonfrom __future__ import print_function 12525cd59fSSerge Guelton 13c769722aSGreg Claytonimport optparse 14c769722aSGreg Claytonimport os 1597e44a0cSGreg Claytonimport platform 16c769722aSGreg Claytonimport sys 171a12dd70SSerge Gueltonimport subprocess 181a12dd70SSerge Guelton 1997e44a0cSGreg Clayton#---------------------------------------------------------------------- 2097e44a0cSGreg Clayton# Code that auto imports LLDB 2197e44a0cSGreg Clayton#---------------------------------------------------------------------- 2297e44a0cSGreg Claytontry: 2397e44a0cSGreg Clayton # Just try for LLDB in case PYTHONPATH is already correctly setup 2497e44a0cSGreg Clayton import lldb 2597e44a0cSGreg Claytonexcept ImportError: 2697e44a0cSGreg Clayton lldb_python_dirs = list() 2797e44a0cSGreg Clayton # lldb is not in the PYTHONPATH, try some defaults for the current platform 2897e44a0cSGreg Clayton platform_system = platform.system() 2997e44a0cSGreg Clayton if platform_system == 'Darwin': 3097e44a0cSGreg Clayton # On Darwin, try the currently selected Xcode directory 31185de8eeSDavide Italiano xcode_dir = subprocess.check_output("xcode-select --print-path", shell=True) 3297e44a0cSGreg Clayton if xcode_dir: 33b9c1b51eSKate Stone lldb_python_dirs.append( 34b9c1b51eSKate Stone os.path.realpath( 35b9c1b51eSKate Stone xcode_dir + 36b9c1b51eSKate Stone '/../SharedFrameworks/LLDB.framework/Resources/Python')) 37b9c1b51eSKate Stone lldb_python_dirs.append( 38b9c1b51eSKate Stone xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python') 39b9c1b51eSKate Stone lldb_python_dirs.append( 40b9c1b51eSKate Stone '/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python') 4197e44a0cSGreg Clayton success = False 4297e44a0cSGreg Clayton for lldb_python_dir in lldb_python_dirs: 4397e44a0cSGreg Clayton if os.path.exists(lldb_python_dir): 4497e44a0cSGreg Clayton if not (sys.path.__contains__(lldb_python_dir)): 4597e44a0cSGreg Clayton sys.path.append(lldb_python_dir) 4697e44a0cSGreg Clayton try: 4797e44a0cSGreg Clayton import lldb 4897e44a0cSGreg Clayton except ImportError: 4997e44a0cSGreg Clayton pass 5097e44a0cSGreg Clayton else: 51525cd59fSSerge Guelton print('imported lldb from: "%s"' % (lldb_python_dir)) 5297e44a0cSGreg Clayton success = True 5397e44a0cSGreg Clayton break 5497e44a0cSGreg Clayton if not success: 55525cd59fSSerge Guelton print("error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly") 5697e44a0cSGreg Clayton sys.exit(1) 5797e44a0cSGreg Clayton 58b9c1b51eSKate Stone 59c769722aSGreg Claytondef print_threads(process, options): 60c769722aSGreg Clayton if options.show_threads: 61c769722aSGreg Clayton for thread in process: 62525cd59fSSerge Guelton print('%s %s' % (thread, thread.GetFrameAtIndex(0))) 63c769722aSGreg Clayton 64b9c1b51eSKate Stone 65c769722aSGreg Claytondef run_commands(command_interpreter, commands): 66c769722aSGreg Clayton return_obj = lldb.SBCommandReturnObject() 67c769722aSGreg Clayton for command in commands: 68c769722aSGreg Clayton command_interpreter.HandleCommand(command, return_obj) 69c769722aSGreg Clayton if return_obj.Succeeded(): 70525cd59fSSerge Guelton print(return_obj.GetOutput()) 71c769722aSGreg Clayton else: 72525cd59fSSerge Guelton print(return_obj) 73c769722aSGreg Clayton if options.stop_on_error: 74c769722aSGreg Clayton break 75c769722aSGreg Clayton 76b9c1b51eSKate Stone 77c769722aSGreg Claytondef main(argv): 78c769722aSGreg Clayton description = '''Debugs a program using the LLDB python API and uses asynchronous broadcast events to watch for process state changes.''' 7997e44a0cSGreg Clayton epilog = '''Examples: 8097e44a0cSGreg Clayton 8197e44a0cSGreg Clayton#---------------------------------------------------------------------- 8297e44a0cSGreg Clayton# Run "/bin/ls" with the arguments "-lAF /tmp/", and set a breakpoint 8397e44a0cSGreg Clayton# at "malloc" and backtrace and read all registers each time we stop 8497e44a0cSGreg Clayton#---------------------------------------------------------------------- 8597e44a0cSGreg Clayton% ./process_events.py --breakpoint malloc --stop-command bt --stop-command 'register read' -- /bin/ls -lAF /tmp/ 8697e44a0cSGreg Clayton 8797e44a0cSGreg Clayton''' 8897e44a0cSGreg Clayton optparse.OptionParser.format_epilog = lambda self, formatter: self.epilog 89b9c1b51eSKate Stone parser = optparse.OptionParser( 90b9c1b51eSKate Stone description=description, 91b9c1b51eSKate Stone prog='process_events', 92b9c1b51eSKate Stone usage='usage: process_events [options] program [arg1 arg2]', 93b9c1b51eSKate Stone epilog=epilog) 94b9c1b51eSKate Stone parser.add_option( 95b9c1b51eSKate Stone '-v', 96b9c1b51eSKate Stone '--verbose', 97b9c1b51eSKate Stone action='store_true', 98b9c1b51eSKate Stone dest='verbose', 99b9c1b51eSKate Stone help="Enable verbose logging.", 100b9c1b51eSKate Stone default=False) 101b9c1b51eSKate Stone parser.add_option( 102b9c1b51eSKate Stone '-b', 103b9c1b51eSKate Stone '--breakpoint', 104b9c1b51eSKate Stone action='append', 105b9c1b51eSKate Stone type='string', 106b9c1b51eSKate Stone metavar='BPEXPR', 107b9c1b51eSKate Stone dest='breakpoints', 108b9c1b51eSKate Stone 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.') 109b9c1b51eSKate Stone parser.add_option( 110b9c1b51eSKate Stone '-a', 111b9c1b51eSKate Stone '--arch', 112b9c1b51eSKate Stone type='string', 113b9c1b51eSKate Stone dest='arch', 114b9c1b51eSKate Stone help='The architecture to use when creating the debug target.', 115b9c1b51eSKate Stone default=None) 116b9c1b51eSKate Stone parser.add_option( 117b9c1b51eSKate Stone '--platform', 118b9c1b51eSKate Stone type='string', 119b9c1b51eSKate Stone metavar='platform', 120b9c1b51eSKate Stone dest='platform', 121b9c1b51eSKate Stone 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".', 122b9c1b51eSKate Stone default=None) 123b9c1b51eSKate Stone parser.add_option( 124b9c1b51eSKate Stone '-l', 125b9c1b51eSKate Stone '--launch-command', 126b9c1b51eSKate Stone action='append', 127b9c1b51eSKate Stone type='string', 128b9c1b51eSKate Stone metavar='CMD', 129b9c1b51eSKate Stone dest='launch_commands', 130b9c1b51eSKate Stone help='LLDB command interpreter commands to run once after the process has launched. This option can be specified more than once.', 131b9c1b51eSKate Stone default=[]) 132b9c1b51eSKate Stone parser.add_option( 133b9c1b51eSKate Stone '-s', 134b9c1b51eSKate Stone '--stop-command', 135b9c1b51eSKate Stone action='append', 136b9c1b51eSKate Stone type='string', 137b9c1b51eSKate Stone metavar='CMD', 138b9c1b51eSKate Stone dest='stop_commands', 139b9c1b51eSKate Stone help='LLDB command interpreter commands to run each time the process stops. This option can be specified more than once.', 140b9c1b51eSKate Stone default=[]) 141b9c1b51eSKate Stone parser.add_option( 142b9c1b51eSKate Stone '-c', 143b9c1b51eSKate Stone '--crash-command', 144b9c1b51eSKate Stone action='append', 145b9c1b51eSKate Stone type='string', 146b9c1b51eSKate Stone metavar='CMD', 147b9c1b51eSKate Stone dest='crash_commands', 148b9c1b51eSKate Stone help='LLDB command interpreter commands to run in case the process crashes. This option can be specified more than once.', 149b9c1b51eSKate Stone default=[]) 150b9c1b51eSKate Stone parser.add_option( 151b9c1b51eSKate Stone '-x', 152b9c1b51eSKate Stone '--exit-command', 153b9c1b51eSKate Stone action='append', 154b9c1b51eSKate Stone type='string', 155b9c1b51eSKate Stone metavar='CMD', 156b9c1b51eSKate Stone dest='exit_commands', 157b9c1b51eSKate Stone help='LLDB command interpreter commands to run once after the process has exited. This option can be specified more than once.', 158b9c1b51eSKate Stone default=[]) 159b9c1b51eSKate Stone parser.add_option( 160b9c1b51eSKate Stone '-T', 161b9c1b51eSKate Stone '--no-threads', 162b9c1b51eSKate Stone action='store_false', 163b9c1b51eSKate Stone dest='show_threads', 164b9c1b51eSKate Stone help="Don't show threads when process stops.", 165b9c1b51eSKate Stone default=True) 166b9c1b51eSKate Stone parser.add_option( 167b9c1b51eSKate Stone '--ignore-errors', 168b9c1b51eSKate Stone action='store_false', 169b9c1b51eSKate Stone dest='stop_on_error', 170b9c1b51eSKate Stone 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.", 171b9c1b51eSKate Stone default=True) 172b9c1b51eSKate Stone parser.add_option( 173b9c1b51eSKate Stone '-n', 174b9c1b51eSKate Stone '--run-count', 175b9c1b51eSKate Stone type='int', 176b9c1b51eSKate Stone dest='run_count', 177b9c1b51eSKate Stone metavar='N', 178b9c1b51eSKate Stone help='How many times to run the process in case the process exits.', 179b9c1b51eSKate Stone default=1) 180b9c1b51eSKate Stone parser.add_option( 181b9c1b51eSKate Stone '-t', 182b9c1b51eSKate Stone '--event-timeout', 183b9c1b51eSKate Stone type='int', 184b9c1b51eSKate Stone dest='event_timeout', 185b9c1b51eSKate Stone metavar='SEC', 186b9c1b51eSKate Stone help='Specify the timeout in seconds to wait for process state change events.', 187b9c1b51eSKate Stone default=lldb.UINT32_MAX) 188b9c1b51eSKate Stone parser.add_option( 189b9c1b51eSKate Stone '-e', 190b9c1b51eSKate Stone '--environment', 191b9c1b51eSKate Stone action='append', 192b9c1b51eSKate Stone type='string', 193b9c1b51eSKate Stone metavar='ENV', 194b9c1b51eSKate Stone dest='env_vars', 195b9c1b51eSKate Stone help='Environment variables to set in the inferior process when launching a process.') 196b9c1b51eSKate Stone parser.add_option( 197b9c1b51eSKate Stone '-d', 198b9c1b51eSKate Stone '--working-dir', 199b9c1b51eSKate Stone type='string', 200b9c1b51eSKate Stone metavar='DIR', 201b9c1b51eSKate Stone dest='working_dir', 202*36597e47SBruce Mitchener help='The current working directory when launching a process.', 203b9c1b51eSKate Stone default=None) 204b9c1b51eSKate Stone parser.add_option( 205b9c1b51eSKate Stone '-p', 206b9c1b51eSKate Stone '--attach-pid', 207b9c1b51eSKate Stone type='int', 208b9c1b51eSKate Stone dest='attach_pid', 209b9c1b51eSKate Stone metavar='PID', 210b9c1b51eSKate Stone help='Specify a process to attach to by process ID.', 211b9c1b51eSKate Stone default=-1) 212b9c1b51eSKate Stone parser.add_option( 213b9c1b51eSKate Stone '-P', 214b9c1b51eSKate Stone '--attach-name', 215b9c1b51eSKate Stone type='string', 216b9c1b51eSKate Stone dest='attach_name', 217b9c1b51eSKate Stone metavar='PROCESSNAME', 218b9c1b51eSKate Stone help='Specify a process to attach to by name.', 219b9c1b51eSKate Stone default=None) 220b9c1b51eSKate Stone parser.add_option( 221b9c1b51eSKate Stone '-w', 222b9c1b51eSKate Stone '--attach-wait', 223b9c1b51eSKate Stone action='store_true', 224b9c1b51eSKate Stone dest='attach_wait', 225b9c1b51eSKate Stone help='Wait for the next process to launch when attaching to a process by name.', 226b9c1b51eSKate Stone default=False) 227c769722aSGreg Clayton try: 228c769722aSGreg Clayton (options, args) = parser.parse_args(argv) 229c769722aSGreg Clayton except: 230c769722aSGreg Clayton return 231984fee5bSGreg Clayton 232984fee5bSGreg Clayton attach_info = None 233984fee5bSGreg Clayton launch_info = None 234984fee5bSGreg Clayton exe = None 235984fee5bSGreg Clayton if args: 236984fee5bSGreg Clayton exe = args.pop(0) 237984fee5bSGreg Clayton launch_info = lldb.SBLaunchInfo(args) 238984fee5bSGreg Clayton if options.env_vars: 239984fee5bSGreg Clayton launch_info.SetEnvironmentEntries(options.env_vars, True) 240984fee5bSGreg Clayton if options.working_dir: 241984fee5bSGreg Clayton launch_info.SetWorkingDirectory(options.working_dir) 242984fee5bSGreg Clayton elif options.attach_pid != -1: 243984fee5bSGreg Clayton if options.run_count == 1: 244984fee5bSGreg Clayton attach_info = lldb.SBAttachInfo(options.attach_pid) 245984fee5bSGreg Clayton else: 246525cd59fSSerge Guelton print("error: --run-count can't be used with the --attach-pid option") 247984fee5bSGreg Clayton sys.exit(1) 248984fee5bSGreg Clayton elif not options.attach_name is None: 249984fee5bSGreg Clayton if options.run_count == 1: 250b9c1b51eSKate Stone attach_info = lldb.SBAttachInfo( 251b9c1b51eSKate Stone options.attach_name, options.attach_wait) 252984fee5bSGreg Clayton else: 253525cd59fSSerge Guelton print("error: --run-count can't be used with the --attach-name option") 254984fee5bSGreg Clayton sys.exit(1) 255984fee5bSGreg Clayton else: 256525cd59fSSerge Guelton print('error: a program path for a program to debug and its arguments are required') 257c769722aSGreg Clayton sys.exit(1) 258c769722aSGreg Clayton 259c769722aSGreg Clayton # Create a new debugger instance 260c769722aSGreg Clayton debugger = lldb.SBDebugger.Create() 261111db4f9SGreg Clayton debugger.SetAsync(True) 262c769722aSGreg Clayton command_interpreter = debugger.GetCommandInterpreter() 263c769722aSGreg Clayton # Create a target from a file and arch 264c769722aSGreg Clayton 265984fee5bSGreg Clayton if exe: 266525cd59fSSerge Guelton print("Creating a target for '%s'" % exe) 267111db4f9SGreg Clayton error = lldb.SBError() 268b9c1b51eSKate Stone target = debugger.CreateTarget( 269b9c1b51eSKate Stone exe, options.arch, options.platform, True, error) 270c769722aSGreg Clayton 271c769722aSGreg Clayton if target: 272c769722aSGreg Clayton 273111db4f9SGreg Clayton # Set any breakpoints that were specified in the args if we are launching. We use the 274b9c1b51eSKate Stone # command line command to take advantage of the shorthand breakpoint 275b9c1b51eSKate Stone # creation 276984fee5bSGreg Clayton if launch_info and options.breakpoints: 277c769722aSGreg Clayton for bp in options.breakpoints: 27897e44a0cSGreg Clayton debugger.HandleCommand("_regexp-break %s" % (bp)) 27997e44a0cSGreg Clayton run_commands(command_interpreter, ['breakpoint list']) 280c769722aSGreg Clayton 281c769722aSGreg Clayton for run_idx in range(options.run_count): 282c769722aSGreg Clayton # Launch the process. Since we specified synchronous mode, we won't return 283c769722aSGreg Clayton # from this function until we hit the breakpoint at main 284984fee5bSGreg Clayton error = lldb.SBError() 285984fee5bSGreg Clayton 286984fee5bSGreg Clayton if launch_info: 287c769722aSGreg Clayton if options.run_count == 1: 288525cd59fSSerge Guelton print('Launching "%s"...' % (exe)) 289c769722aSGreg Clayton else: 290525cd59fSSerge Guelton print('Launching "%s"... (launch %u of %u)' % (exe, run_idx + 1, options.run_count)) 291c769722aSGreg Clayton 292984fee5bSGreg Clayton process = target.Launch(launch_info, error) 293984fee5bSGreg Clayton else: 294984fee5bSGreg Clayton if options.attach_pid != -1: 295525cd59fSSerge Guelton print('Attaching to process %i...' % (options.attach_pid)) 296984fee5bSGreg Clayton else: 297984fee5bSGreg Clayton if options.attach_wait: 298525cd59fSSerge Guelton print('Waiting for next to process named "%s" to launch...' % (options.attach_name)) 299984fee5bSGreg Clayton else: 300525cd59fSSerge Guelton print('Attaching to existing process named "%s"...' % (options.attach_name)) 301984fee5bSGreg Clayton process = target.Attach(attach_info, error) 302c769722aSGreg Clayton 303c769722aSGreg Clayton # Make sure the launch went ok 304984fee5bSGreg Clayton if process and process.GetProcessID() != lldb.LLDB_INVALID_PROCESS_ID: 3054d48e5b3SGreg Clayton 306c769722aSGreg Clayton pid = process.GetProcessID() 307525cd59fSSerge Guelton print('Process is %i' % (pid)) 3084d48e5b3SGreg Clayton if attach_info: 309b9c1b51eSKate Stone # continue process if we attached as we won't get an 310b9c1b51eSKate Stone # initial event 3114d48e5b3SGreg Clayton process.Continue() 3124d48e5b3SGreg Clayton 313111db4f9SGreg Clayton listener = debugger.GetListener() 314c769722aSGreg Clayton # sign up for process state change events 315c769722aSGreg Clayton stop_idx = 0 316c769722aSGreg Clayton done = False 317c769722aSGreg Clayton while not done: 318c769722aSGreg Clayton event = lldb.SBEvent() 319c769722aSGreg Clayton if listener.WaitForEvent(options.event_timeout, event): 320111db4f9SGreg Clayton if lldb.SBProcess.EventIsProcessEvent(event): 321c769722aSGreg Clayton state = lldb.SBProcess.GetStateFromEvent(event) 32296eb9ab0SGreg Clayton if state == lldb.eStateInvalid: 32396eb9ab0SGreg Clayton # Not a state event 324525cd59fSSerge Guelton print('process event = %s' % (event)) 32596eb9ab0SGreg Clayton else: 326525cd59fSSerge Guelton print("process state changed event: %s" % (lldb.SBDebugger.StateAsCString(state))) 327c769722aSGreg Clayton if state == lldb.eStateStopped: 328c769722aSGreg Clayton if stop_idx == 0: 329984fee5bSGreg Clayton if launch_info: 330525cd59fSSerge Guelton print("process %u launched" % (pid)) 331b9c1b51eSKate Stone run_commands( 332b9c1b51eSKate Stone command_interpreter, ['breakpoint list']) 333984fee5bSGreg Clayton else: 334525cd59fSSerge Guelton print("attached to process %u" % (pid)) 335984fee5bSGreg Clayton for m in target.modules: 336525cd59fSSerge Guelton print(m) 337984fee5bSGreg Clayton if options.breakpoints: 338984fee5bSGreg Clayton for bp in options.breakpoints: 339b9c1b51eSKate Stone debugger.HandleCommand( 340b9c1b51eSKate Stone "_regexp-break %s" % (bp)) 341b9c1b51eSKate Stone run_commands( 342b9c1b51eSKate Stone command_interpreter, ['breakpoint list']) 343b9c1b51eSKate Stone run_commands( 344b9c1b51eSKate Stone command_interpreter, options.launch_commands) 345c769722aSGreg Clayton else: 346c769722aSGreg Clayton if options.verbose: 347525cd59fSSerge Guelton print("process %u stopped" % (pid)) 348b9c1b51eSKate Stone run_commands( 349b9c1b51eSKate Stone command_interpreter, options.stop_commands) 350c769722aSGreg Clayton stop_idx += 1 351c769722aSGreg Clayton print_threads(process, options) 352525cd59fSSerge Guelton print("continuing process %u" % (pid)) 353c769722aSGreg Clayton process.Continue() 354c769722aSGreg Clayton elif state == lldb.eStateExited: 355c769722aSGreg Clayton exit_desc = process.GetExitDescription() 356c769722aSGreg Clayton if exit_desc: 357525cd59fSSerge Guelton print("process %u exited with status %u: %s" % (pid, process.GetExitStatus(), exit_desc)) 358c769722aSGreg Clayton else: 359525cd59fSSerge Guelton print("process %u exited with status %u" % (pid, process.GetExitStatus())) 360b9c1b51eSKate Stone run_commands( 361b9c1b51eSKate Stone command_interpreter, options.exit_commands) 362c769722aSGreg Clayton done = True 363c769722aSGreg Clayton elif state == lldb.eStateCrashed: 364525cd59fSSerge Guelton print("process %u crashed" % (pid)) 365c769722aSGreg Clayton print_threads(process, options) 366b9c1b51eSKate Stone run_commands( 367b9c1b51eSKate Stone command_interpreter, options.crash_commands) 368c769722aSGreg Clayton done = True 369c769722aSGreg Clayton elif state == lldb.eStateDetached: 370525cd59fSSerge Guelton print("process %u detached" % (pid)) 371c769722aSGreg Clayton done = True 372c769722aSGreg Clayton elif state == lldb.eStateRunning: 373b9c1b51eSKate Stone # process is running, don't say anything, 374b9c1b51eSKate Stone # we will always get one of these after 375b9c1b51eSKate Stone # resuming 376c769722aSGreg Clayton if options.verbose: 377525cd59fSSerge Guelton print("process %u resumed" % (pid)) 378c769722aSGreg Clayton elif state == lldb.eStateUnloaded: 379525cd59fSSerge Guelton print("process %u unloaded, this shouldn't happen" % (pid)) 380c769722aSGreg Clayton done = True 381c769722aSGreg Clayton elif state == lldb.eStateConnected: 382525cd59fSSerge Guelton print("process connected") 383c769722aSGreg Clayton elif state == lldb.eStateAttaching: 384525cd59fSSerge Guelton print("process attaching") 385c769722aSGreg Clayton elif state == lldb.eStateLaunching: 386525cd59fSSerge Guelton print("process launching") 387c769722aSGreg Clayton else: 388525cd59fSSerge Guelton print('event = %s' % (event)) 38996eb9ab0SGreg Clayton else: 390c769722aSGreg Clayton # timeout waiting for an event 391525cd59fSSerge Guelton print("no process event for %u seconds, killing the process..." % (options.event_timeout)) 392c769722aSGreg Clayton done = True 39396eb9ab0SGreg Clayton # Now that we are done dump the stdout and stderr 39496eb9ab0SGreg Clayton process_stdout = process.GetSTDOUT(1024) 39596eb9ab0SGreg Clayton if process_stdout: 396525cd59fSSerge Guelton print("Process STDOUT:\n%s" % (process_stdout)) 39796eb9ab0SGreg Clayton while process_stdout: 39896eb9ab0SGreg Clayton process_stdout = process.GetSTDOUT(1024) 399525cd59fSSerge Guelton print(process_stdout) 40096eb9ab0SGreg Clayton process_stderr = process.GetSTDERR(1024) 40196eb9ab0SGreg Clayton if process_stderr: 402525cd59fSSerge Guelton print("Process STDERR:\n%s" % (process_stderr)) 40396eb9ab0SGreg Clayton while process_stderr: 40496eb9ab0SGreg Clayton process_stderr = process.GetSTDERR(1024) 405525cd59fSSerge Guelton print(process_stderr) 406c769722aSGreg Clayton process.Kill() # kill the process 407984fee5bSGreg Clayton else: 408984fee5bSGreg Clayton if error: 409525cd59fSSerge Guelton print(error) 410984fee5bSGreg Clayton else: 411984fee5bSGreg Clayton if launch_info: 412525cd59fSSerge Guelton print('error: launch failed') 413984fee5bSGreg Clayton else: 414525cd59fSSerge Guelton print('error: attach failed') 415c769722aSGreg Clayton 416c769722aSGreg Clayton lldb.SBDebugger.Terminate() 417c769722aSGreg Clayton 418c769722aSGreg Claytonif __name__ == '__main__': 419c769722aSGreg Clayton main(sys.argv[1:]) 420