diff --git a/lldb/utils/test/README-run-until-faulted b/lldb/utils/test/README-run-until-faulted new file mode 100644 index 000000000000..f89f8636d627 --- /dev/null +++ b/lldb/utils/test/README-run-until-faulted @@ -0,0 +1,18 @@ +A example usage of the Python script run-until-faulted.py: + +[18:20:29] johnny:/Volumes/data/lldb/svn/trunk/utils/test $ ./run-until-faulted.py -l /Volumes/data/lldb/svn/trunk/build/Debug/lldb -e './a.out' +lldb command: /Volumes/data/lldb/svn/trunk/build/Debug/lldb +executable: ./a.out +executable options: +sending file command.... +sending process launch -- (iteration: 0) + +* thread #1: tid = 0x2d03, 0x0000000100000eef a.out`main + 39 at main.c:7, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) + 4 { + 5 int *null_ptr = 0; + 6 printf("Hello, fault!\n"); +-> 7 printf("Now segfault %d\n", *null_ptr); + 8 } + +(lldb) q +[18:20:40] johnny:/Volumes/data/lldb/svn/trunk/utils/test $ diff --git a/lldb/utils/test/main.c b/lldb/utils/test/main.c new file mode 100644 index 000000000000..9caf9d8c97d4 --- /dev/null +++ b/lldb/utils/test/main.c @@ -0,0 +1,8 @@ +#include + +int main(int argc, const char* argv[]) +{ + int *null_ptr = 0; + printf("Hello, fault!\n"); + printf("Now segfault %d\n", *null_ptr); +} diff --git a/lldb/utils/test/run-until-faulted.py b/lldb/utils/test/run-until-faulted.py new file mode 100755 index 000000000000..f338d7bd969e --- /dev/null +++ b/lldb/utils/test/run-until-faulted.py @@ -0,0 +1,118 @@ +#!/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 command...." + lldb.sendline('file %s' % exe) + lldb.expect(prompt) + #print "lldb.buffer:--->", lldb.buffer, "<---" + #print "lldb.before:--->", lldb.before, "<---" + #print "lldb.after:--->", lldb.buffer, "<----" + + # Loop until it faults.... + count = 0 + #while True: + # count = count + 1 + for i in range(10): + count = i + print "sending process launch -- %s (iteration: %d)" % (exe_options, count) + lldb.sendline('process launch -- %s' % exe_options) + index = lldb.expect(['Process .* exited with status', + 'Process .* stopped', + pexpect.TIMEOUT]) + #print "lldb.buffer:--->", lldb.buffer, "<---" + #print "lldb.before:--->", lldb.before, "<----" + #print "lldb.after:--->", lldb.buffer, "<----" + 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="""\ +Run a program via lldb until it fails. +The lldb executable is located via your PATH env variable, if not specified. + +Usage: %prog [options] +""") + 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()