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