#!/usr/bin/env python """ Run a program via lldb until it fails. The lldb executable is located via your PATH env variable, if not specified. """ import os import sys from optparse import OptionParser def is_exe(fpath): """Check whether fpath is an executable.""" return os.path.isfile(fpath) and os.access(fpath, os.X_OK) def which(program): """Find the full path to a program, or return None.""" fpath, fname = os.path.split(program) if fpath: if is_exe(program): return program else: for path in os.environ["PATH"].split(os.pathsep): exe_file = os.path.join(path, program) if is_exe(exe_file): return exe_file return None def do_lldb_launch_loop(lldb_command, exe, exe_options): from cStringIO import StringIO import pexpect import time prompt = "\(lldb\) " lldb = pexpect.spawn(lldb_command) # Turn on logging for what lldb sends back. lldb.logfile_read = sys.stdout lldb.expect(prompt) # Now issue the file command. # print "sending 'file %s' command..." % exe lldb.sendline('file %s' % exe) lldb.expect(prompt) # Loop until it faults.... count = 0 # while True: # count = count + 1 for i in range(100): count = i # print "sending 'process launch -- %s' command... (iteration: %d)" % # (exe_options, count) lldb.sendline('process launch -- %s' % exe_options) index = lldb.expect(['Process .* exited with status', 'Process .* stopped', pexpect.TIMEOUT]) if index == 0: # We'll try again later. time.sleep(3) elif index == 1: # Perfect, our process had stopped; break out of the loop. break elif index == 2: # Something went wrong. print "TIMEOUT occurred:", str(lldb) # Give control of lldb shell to the user. lldb.interact() def main(): # This is to set up the Python path to include the pexpect-2.4 dir. # Remember to update this when/if things change. scriptPath = sys.path[0] sys.path.append( os.path.join( scriptPath, os.pardir, os.pardir, 'test', 'pexpect-2.4')) parser = OptionParser(usage="""\ %prog [options] Run a program via lldb until it fails. The lldb executable is located via your PATH env variable, if not specified.\ """) parser.add_option('-l', '--lldb-command', type='string', action='store', metavar='LLDB_COMMAND', default='lldb', dest='lldb_command', help='Full path to your lldb command') parser.add_option( '-e', '--executable', type='string', action='store', dest='exe', help="""(Mandatory) The executable to launch via lldb.""") parser.add_option( '-o', '--options', type='string', action='store', default='', dest='exe_options', help="""The args/options passed to the launched program, if specified.""") opts, args = parser.parse_args() lldb_command = which(opts.lldb_command) if not opts.exe: parser.print_help() sys.exit(1) exe = opts.exe exe_options = opts.exe_options # We have parsed the options. print "lldb command:", lldb_command print "executable:", exe print "executable options:", exe_options do_lldb_launch_loop(lldb_command, exe, exe_options) if __name__ == '__main__': main()