1#!/usr/bin/env python 2 3""" 4Run a program via lldb until it fails. 5The lldb executable is located via your PATH env variable, if not specified. 6""" 7 8import os 9import sys 10from optparse import OptionParser 11 12def is_exe(fpath): 13 """Check whether fpath is an executable.""" 14 return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 15 16def which(program): 17 """Find the full path to a program, or return None.""" 18 fpath, fname = os.path.split(program) 19 if fpath: 20 if is_exe(program): 21 return program 22 else: 23 for path in os.environ["PATH"].split(os.pathsep): 24 exe_file = os.path.join(path, program) 25 if is_exe(exe_file): 26 return exe_file 27 return None 28 29def do_lldb_launch_loop(lldb_command, exe, exe_options): 30 from cStringIO import StringIO 31 import pexpect, time 32 33 prompt = "\(lldb\) " 34 lldb = pexpect.spawn(lldb_command) 35 # Turn on logging for what lldb sends back. 36 lldb.logfile_read = sys.stdout 37 lldb.expect(prompt) 38 39 # Now issue the file command. 40 #print "sending 'file %s' command..." % exe 41 lldb.sendline('file %s' % exe) 42 lldb.expect(prompt) 43 44 # Loop until it faults.... 45 count = 0 46 #while True: 47 # count = count + 1 48 for i in range(100): 49 count = i 50 #print "sending 'process launch -- %s' command... (iteration: %d)" % (exe_options, count) 51 lldb.sendline('process launch -- %s' % exe_options) 52 index = lldb.expect(['Process .* exited with status', 53 'Process .* stopped', 54 pexpect.TIMEOUT]) 55 if index == 0: 56 # We'll try again later. 57 time.sleep(3) 58 elif index == 1: 59 # Perfect, our process had stopped; break out of the loop. 60 break; 61 elif index == 2: 62 # Something went wrong. 63 print "TIMEOUT occurred:", str(lldb) 64 65 # Give control of lldb shell to the user. 66 lldb.interact() 67 68def main(): 69 # This is to set up the Python path to include the pexpect-2.4 dir. 70 # Remember to update this when/if things change. 71 scriptPath = sys.path[0] 72 sys.path.append(os.path.join(scriptPath, os.pardir, os.pardir, 'test', 'pexpect-2.4')) 73 74 parser = OptionParser(usage="""\ 75%prog [options] 76Run a program via lldb until it fails. 77The lldb executable is located via your PATH env variable, if not specified.\ 78""") 79 parser.add_option('-l', '--lldb-command', 80 type='string', action='store', metavar='LLDB_COMMAND', 81 default='lldb', dest='lldb_command', 82 help='Full path to your lldb command') 83 parser.add_option('-e', '--executable', 84 type='string', action='store', 85 dest='exe', 86 help="""(Mandatory) The executable to launch via lldb.""") 87 parser.add_option('-o', '--options', 88 type='string', action='store', 89 default = '', dest='exe_options', 90 help="""The args/options passed to the launched program, if specified.""") 91 92 opts, args = parser.parse_args() 93 94 lldb_command = which(opts.lldb_command) 95 96 if not opts.exe: 97 parser.print_help() 98 sys.exit(1) 99 exe = opts.exe 100 101 exe_options = opts.exe_options 102 103 # We have parsed the options. 104 print "lldb command:", lldb_command 105 print "executable:", exe 106 print "executable options:", exe_options 107 108 do_lldb_launch_loop(lldb_command, exe, exe_options) 109 110if __name__ == '__main__': 111 main() 112