#!/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, 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()