forked from OSchip/llvm-project
[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
This commit is contained in:
parent
bf94c96007
commit
7ce1a93efd
|
@ -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')
|
Loading…
Reference in New Issue