diff options
author | Jonas Devlieghere <jonas@devlieghere.com> | 2020-04-15 10:24:34 -0700 |
---|---|---|
committer | Jonas Devlieghere <jonas@devlieghere.com> | 2020-04-15 10:55:41 -0700 |
commit | 7ce1a93efd0700770f7c5c368999a44db0d222e8 (patch) | |
tree | 8b7e90262e0f61a3a23dea08f244e9f2681a2218 /lldb/scripts | |
parent | bf94c960071d338b7157ac7dee8120df50d5600f (diff) | |
download | llvm-7ce1a93efd0700770f7c5c368999a44db0d222e8.tar.gz |
[lldb/Scripts] Add script to replay multiple reproducers
Script to replay reproducers in parallel using the command line driver.
This is used for active replay (stage 1 as described in the RFC on
lldb-dev [1]).
[1] http://lists.llvm.org/pipermail/lldb-dev/2020-April/016100.html
Differential revision: https://reviews.llvm.org/D77608
Diffstat (limited to 'lldb/scripts')
-rwxr-xr-x | lldb/scripts/reproducer-replay.py | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/lldb/scripts/reproducer-replay.py b/lldb/scripts/reproducer-replay.py new file mode 100755 index 000000000000..5e9fab176ab6 --- /dev/null +++ b/lldb/scripts/reproducer-replay.py @@ -0,0 +1,100 @@ +#! /usr/bin/env python3 + +from multiprocessing import Pool +import multiprocessing +import argparse +import tempfile +import logging +import os +import subprocess + + +def run_reproducer(path): + proc = subprocess.Popen([LLDB, '--replay', path], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + reason = None + try: + outs, errs = proc.communicate(timeout=TIMEOUT) + result = 'PASSED' if proc.returncode == 0 else 'FAILED' + if proc.returncode != 0: + outs = outs.decode() + errs = errs.decode() + # Do some pattern matching to find out the cause of the failure. + if 'Encountered unexpected packet during replay' in errs: + reason = 'Unexpected packet' + elif 'Assertion failed' in errs: + reason = 'Assertion failed' + elif 'UNREACHABLE' in errs: + reason = 'Unreachable executed' + elif 'Segmentation fault' in errs: + reason = 'Segmentation fault' + elif 'Illegal instruction' in errs: + reason = 'Illegal instruction' + else: + reason = f'Exit code {proc.returncode}' + except subprocess.TimeoutExpired: + proc.kill() + outs, errs = proc.communicate() + result = 'TIMEOUT' + + reason_str = f' ({reason})' if reason else '' + print(f'{result}: {path}{reason_str}') + + +def find_reproducers(path): + for root, dirs, files in os.walk(path): + for dir in dirs: + _, extension = os.path.splitext(dir) + if dir.startswith('Test') and extension == '.py': + yield os.path.join(root, dir) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description='LLDB API Test Replay Driver. ' + 'Replay one or more reproducers in parallel using the specified LLDB driver. ' + 'The script will look for reproducers generated by the API lit test suite. ' + 'To generate the reproducers, pass --param \'lldb-run-with-repro=capture\' to lit.' + ) + parser.add_argument( + '-j', + '--threads', + type=int, + default=multiprocessing.cpu_count(), + help='Number of threads. The number of CPU threads if not specified.') + parser.add_argument( + '-t', + '--timeout', + type=int, + default=60, + help='Replay timeout in seconds. 60 seconds if not specified.') + parser.add_argument( + '-p', + '--path', + type=str, + default=os.getcwd(), + help= + 'Path to the directory containing the reproducers. The current working directory if not specified.' + ) + parser.add_argument('-l', + '--lldb', + type=str, + required=True, + help='Path to the LLDB command line driver') + args = parser.parse_args() + + global LLDB + global TIMEOUT + LLDB = args.lldb + TIMEOUT = args.timeout + + print( + f'Replaying reproducers in {args.path} with {args.threads} threads and a {args.timeout} seconds timeout' + ) + + try: + pool = Pool(args.threads) + pool.map(run_reproducer, find_reproducers(args.path)) + except KeyboardInterrupt: + print('Interrupted') |