2011-04-02 09:20:28 +08:00
|
|
|
#!/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.
|
Make 'run-until-faulted.py' script more interesting by modifying the example main.c program
to seg fault randomly instead of deterministically.
Example:
[15:10:43] johnny:/Volumes/data/lldb/svn/trunk/utils/test $ clang -g main.c
[15:10:46] johnny:/Volumes/data/lldb/svn/trunk/utils/test $ ./run-until-faulted.py -l $PWD/../../build/Debug/lldb -e a.out
lldb command: /Volumes/data/lldb/svn/trunk/utils/test/../../build/Debug/lldb
executable: a.out
executable options:
(lldb) sending 'file a.out' command...
file a.out
Current executable set to 'a.out' (x86_64).
(lldb) sending 'process launch -- ' command... (iteration: 0)
process launch --
Process 63630 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=9
Better luck next time!
[KProcess 63630 exited with status = 0 (0x00000000)
(lldb) sending 'process launch -- ' command... (iteration: 1)
process launch --
Process 63633 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
[KProcess 63633 exited with status = 0 (0x00000000)
sending 'process launch -- ' command... (iteration: 2)
[KHello, fault!
val=0
Better luck next time!
(lldb) process launch --
Process 63637 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=15
Better luck next time!
[KProcess 63637 exited with status = 0 (0x00000000)
(lldb) sending 'process launch -- ' command... (iteration: 3)
process launch --
Process 63640 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=2
Better luck next time!
[KProcess 63640 exited with status = 0 (0x00000000)
sending 'process launch -- ' command... (iteration: 4)
(lldb) process launch --
Process 63643 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
[KProcess 63643 stopped
* thread #1: tid = 0x2d03, 0x0000000100000e93 a.out`main + 99 at main.c:11, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000100000e93 a.out`main + 99 at main.c:11
8 u_int32_t val = (arc4random() & 0x0f);
9 printf("val=%u\n", val);
10 if (val == 0x07) // Lucky 7 :-)
-> 11 printf("Now segfault %d\n", *null_ptr);
12 else
13 printf("Better luck next time!\n");
14 }
(lldb)
* thread #1: tid = 0x2d03, 0x0000000100000e93 a.out`main + 99 at main.c:11, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000100000e93 a.out`main + 99 at main.c:11
8 u_int32_t val = (arc4random() & 0x0f);
9 printf("val=%u\n", val);
10 if (val == 0x07) // Lucky 7 :-)
-> 11 printf("Now segfault %d\n", *null_ptr);
12 else
13 printf("Better luck next time!\n");
14 }
[KHello, fault!
val=7
(lldb)
llvm-svn: 132430
2011-06-02 06:12:27 +08:00
|
|
|
lldb.logfile_read = sys.stdout
|
2011-04-02 09:20:28 +08:00
|
|
|
lldb.expect(prompt)
|
|
|
|
|
|
|
|
# Now issue the file command.
|
2011-06-02 07:53:57 +08:00
|
|
|
#print "sending 'file %s' command..." % exe
|
2011-04-02 09:20:28 +08:00
|
|
|
lldb.sendline('file %s' % exe)
|
|
|
|
lldb.expect(prompt)
|
|
|
|
|
|
|
|
# Loop until it faults....
|
|
|
|
count = 0
|
|
|
|
#while True:
|
|
|
|
# count = count + 1
|
Make 'run-until-faulted.py' script more interesting by modifying the example main.c program
to seg fault randomly instead of deterministically.
Example:
[15:10:43] johnny:/Volumes/data/lldb/svn/trunk/utils/test $ clang -g main.c
[15:10:46] johnny:/Volumes/data/lldb/svn/trunk/utils/test $ ./run-until-faulted.py -l $PWD/../../build/Debug/lldb -e a.out
lldb command: /Volumes/data/lldb/svn/trunk/utils/test/../../build/Debug/lldb
executable: a.out
executable options:
(lldb) sending 'file a.out' command...
file a.out
Current executable set to 'a.out' (x86_64).
(lldb) sending 'process launch -- ' command... (iteration: 0)
process launch --
Process 63630 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=9
Better luck next time!
[KProcess 63630 exited with status = 0 (0x00000000)
(lldb) sending 'process launch -- ' command... (iteration: 1)
process launch --
Process 63633 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
[KProcess 63633 exited with status = 0 (0x00000000)
sending 'process launch -- ' command... (iteration: 2)
[KHello, fault!
val=0
Better luck next time!
(lldb) process launch --
Process 63637 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=15
Better luck next time!
[KProcess 63637 exited with status = 0 (0x00000000)
(lldb) sending 'process launch -- ' command... (iteration: 3)
process launch --
Process 63640 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=2
Better luck next time!
[KProcess 63640 exited with status = 0 (0x00000000)
sending 'process launch -- ' command... (iteration: 4)
(lldb) process launch --
Process 63643 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
[KProcess 63643 stopped
* thread #1: tid = 0x2d03, 0x0000000100000e93 a.out`main + 99 at main.c:11, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000100000e93 a.out`main + 99 at main.c:11
8 u_int32_t val = (arc4random() & 0x0f);
9 printf("val=%u\n", val);
10 if (val == 0x07) // Lucky 7 :-)
-> 11 printf("Now segfault %d\n", *null_ptr);
12 else
13 printf("Better luck next time!\n");
14 }
(lldb)
* thread #1: tid = 0x2d03, 0x0000000100000e93 a.out`main + 99 at main.c:11, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000100000e93 a.out`main + 99 at main.c:11
8 u_int32_t val = (arc4random() & 0x0f);
9 printf("val=%u\n", val);
10 if (val == 0x07) // Lucky 7 :-)
-> 11 printf("Now segfault %d\n", *null_ptr);
12 else
13 printf("Better luck next time!\n");
14 }
[KHello, fault!
val=7
(lldb)
llvm-svn: 132430
2011-06-02 06:12:27 +08:00
|
|
|
for i in range(100):
|
2011-04-02 09:20:28 +08:00
|
|
|
count = i
|
2011-06-02 07:53:57 +08:00
|
|
|
#print "sending 'process launch -- %s' command... (iteration: %d)" % (exe_options, count)
|
2011-04-02 09:20:28 +08:00
|
|
|
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="""\
|
Make 'run-until-faulted.py' script more interesting by modifying the example main.c program
to seg fault randomly instead of deterministically.
Example:
[15:10:43] johnny:/Volumes/data/lldb/svn/trunk/utils/test $ clang -g main.c
[15:10:46] johnny:/Volumes/data/lldb/svn/trunk/utils/test $ ./run-until-faulted.py -l $PWD/../../build/Debug/lldb -e a.out
lldb command: /Volumes/data/lldb/svn/trunk/utils/test/../../build/Debug/lldb
executable: a.out
executable options:
(lldb) sending 'file a.out' command...
file a.out
Current executable set to 'a.out' (x86_64).
(lldb) sending 'process launch -- ' command... (iteration: 0)
process launch --
Process 63630 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=9
Better luck next time!
[KProcess 63630 exited with status = 0 (0x00000000)
(lldb) sending 'process launch -- ' command... (iteration: 1)
process launch --
Process 63633 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
[KProcess 63633 exited with status = 0 (0x00000000)
sending 'process launch -- ' command... (iteration: 2)
[KHello, fault!
val=0
Better luck next time!
(lldb) process launch --
Process 63637 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=15
Better luck next time!
[KProcess 63637 exited with status = 0 (0x00000000)
(lldb) sending 'process launch -- ' command... (iteration: 3)
process launch --
Process 63640 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=2
Better luck next time!
[KProcess 63640 exited with status = 0 (0x00000000)
sending 'process launch -- ' command... (iteration: 4)
(lldb) process launch --
Process 63643 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
[KProcess 63643 stopped
* thread #1: tid = 0x2d03, 0x0000000100000e93 a.out`main + 99 at main.c:11, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000100000e93 a.out`main + 99 at main.c:11
8 u_int32_t val = (arc4random() & 0x0f);
9 printf("val=%u\n", val);
10 if (val == 0x07) // Lucky 7 :-)
-> 11 printf("Now segfault %d\n", *null_ptr);
12 else
13 printf("Better luck next time!\n");
14 }
(lldb)
* thread #1: tid = 0x2d03, 0x0000000100000e93 a.out`main + 99 at main.c:11, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000100000e93 a.out`main + 99 at main.c:11
8 u_int32_t val = (arc4random() & 0x0f);
9 printf("val=%u\n", val);
10 if (val == 0x07) // Lucky 7 :-)
-> 11 printf("Now segfault %d\n", *null_ptr);
12 else
13 printf("Better luck next time!\n");
14 }
[KHello, fault!
val=7
(lldb)
llvm-svn: 132430
2011-06-02 06:12:27 +08:00
|
|
|
%prog [options]
|
2011-04-02 09:20:28 +08:00
|
|
|
Run a program via lldb until it fails.
|
Make 'run-until-faulted.py' script more interesting by modifying the example main.c program
to seg fault randomly instead of deterministically.
Example:
[15:10:43] johnny:/Volumes/data/lldb/svn/trunk/utils/test $ clang -g main.c
[15:10:46] johnny:/Volumes/data/lldb/svn/trunk/utils/test $ ./run-until-faulted.py -l $PWD/../../build/Debug/lldb -e a.out
lldb command: /Volumes/data/lldb/svn/trunk/utils/test/../../build/Debug/lldb
executable: a.out
executable options:
(lldb) sending 'file a.out' command...
file a.out
Current executable set to 'a.out' (x86_64).
(lldb) sending 'process launch -- ' command... (iteration: 0)
process launch --
Process 63630 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=9
Better luck next time!
[KProcess 63630 exited with status = 0 (0x00000000)
(lldb) sending 'process launch -- ' command... (iteration: 1)
process launch --
Process 63633 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
[KProcess 63633 exited with status = 0 (0x00000000)
sending 'process launch -- ' command... (iteration: 2)
[KHello, fault!
val=0
Better luck next time!
(lldb) process launch --
Process 63637 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=15
Better luck next time!
[KProcess 63637 exited with status = 0 (0x00000000)
(lldb) sending 'process launch -- ' command... (iteration: 3)
process launch --
Process 63640 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
Hello, fault!
val=2
Better luck next time!
[KProcess 63640 exited with status = 0 (0x00000000)
sending 'process launch -- ' command... (iteration: 4)
(lldb) process launch --
Process 63643 launched: '/Volumes/data/lldb/svn/trunk/utils/test/a.out' (x86_64)
[KProcess 63643 stopped
* thread #1: tid = 0x2d03, 0x0000000100000e93 a.out`main + 99 at main.c:11, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000100000e93 a.out`main + 99 at main.c:11
8 u_int32_t val = (arc4random() & 0x0f);
9 printf("val=%u\n", val);
10 if (val == 0x07) // Lucky 7 :-)
-> 11 printf("Now segfault %d\n", *null_ptr);
12 else
13 printf("Better luck next time!\n");
14 }
(lldb)
* thread #1: tid = 0x2d03, 0x0000000100000e93 a.out`main + 99 at main.c:11, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000100000e93 a.out`main + 99 at main.c:11
8 u_int32_t val = (arc4random() & 0x0f);
9 printf("val=%u\n", val);
10 if (val == 0x07) // Lucky 7 :-)
-> 11 printf("Now segfault %d\n", *null_ptr);
12 else
13 printf("Better luck next time!\n");
14 }
[KHello, fault!
val=7
(lldb)
llvm-svn: 132430
2011-06-02 06:12:27 +08:00
|
|
|
The lldb executable is located via your PATH env variable, if not specified.\
|
2011-04-02 09:20:28 +08:00
|
|
|
""")
|
|
|
|
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()
|