reduce.py: improved --segfault / added detection of "hang" caused by reduced code / cleanups (#3693)
This commit is contained in:
parent
59837be152
commit
4f508c93c4
|
@ -1,7 +1,9 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
# TODO: add --hang option to detect code which impacts the analysis time
|
||||||
def show_syntax():
|
def show_syntax():
|
||||||
print('Syntax:')
|
print('Syntax:')
|
||||||
print(' reduce.py --cmd=<full command> --expected=<expected text output> --file=<source file> [--segfault]')
|
print(' reduce.py --cmd=<full command> --expected=<expected text output> --file=<source file> [--segfault]')
|
||||||
|
@ -17,7 +19,9 @@ CMD = None
|
||||||
EXPECTED = None
|
EXPECTED = None
|
||||||
SEGFAULT = False
|
SEGFAULT = False
|
||||||
FILE = None
|
FILE = None
|
||||||
|
ORGFILE = None
|
||||||
BACKUPFILE = None
|
BACKUPFILE = None
|
||||||
|
TIMEOUTFILE = None
|
||||||
for arg in sys.argv[1:]:
|
for arg in sys.argv[1:]:
|
||||||
if arg.startswith('--cmd='):
|
if arg.startswith('--cmd='):
|
||||||
CMD = arg[arg.find('=') + 1:]
|
CMD = arg[arg.find('=') + 1:]
|
||||||
|
@ -25,7 +29,9 @@ for arg in sys.argv[1:]:
|
||||||
EXPECTED = arg[arg.find('=') + 1:]
|
EXPECTED = arg[arg.find('=') + 1:]
|
||||||
elif arg.startswith('--file='):
|
elif arg.startswith('--file='):
|
||||||
FILE = arg[arg.find('=') + 1:]
|
FILE = arg[arg.find('=') + 1:]
|
||||||
|
ORGFILE = FILE + '.org'
|
||||||
BACKUPFILE = FILE + '.bak'
|
BACKUPFILE = FILE + '.bak'
|
||||||
|
TIMEOUTFILE = FILE + '.timeout'
|
||||||
elif arg == '--segfault':
|
elif arg == '--segfault':
|
||||||
SEGFAULT = True
|
SEGFAULT = True
|
||||||
|
|
||||||
|
@ -37,6 +43,11 @@ if not SEGFAULT and EXPECTED is None:
|
||||||
print('Abort: No --expected')
|
print('Abort: No --expected')
|
||||||
show_syntax()
|
show_syntax()
|
||||||
|
|
||||||
|
# need to add '--error-exitcode=0' so detected issues will not be interpreted as a crash
|
||||||
|
if SEGFAULT and not '--error-exitcode=0' in CMD:
|
||||||
|
print("Adding '--error-exitcode=0' to --cmd")
|
||||||
|
CMD = CMD + ' --error-exitcode=0'
|
||||||
|
|
||||||
if FILE is None:
|
if FILE is None:
|
||||||
print('Abort: No --file')
|
print('Abort: No --file')
|
||||||
show_syntax()
|
show_syntax()
|
||||||
|
@ -49,9 +60,22 @@ else:
|
||||||
print('FILE=' + FILE)
|
print('FILE=' + FILE)
|
||||||
|
|
||||||
|
|
||||||
def runtool():
|
def runtool(filedata=None):
|
||||||
|
timeout = None
|
||||||
|
if elapsed_time:
|
||||||
|
timeout = elapsed_time * 2
|
||||||
p = subprocess.Popen(CMD.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
p = subprocess.Popen(CMD.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
comm = p.communicate()
|
try:
|
||||||
|
comm = p.communicate(timeout=timeout)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
print('timeout')
|
||||||
|
p.kill()
|
||||||
|
p.communicate()
|
||||||
|
if filedata:
|
||||||
|
writefile(TIMEOUTFILE, filedata)
|
||||||
|
return False
|
||||||
|
#print(p.returncode)
|
||||||
|
#print(comm)
|
||||||
if SEGFAULT:
|
if SEGFAULT:
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
return True
|
return True
|
||||||
|
@ -78,7 +102,7 @@ def replaceandrun(what, filedata, i, line):
|
||||||
bak = filedata[i]
|
bak = filedata[i]
|
||||||
filedata[i] = line
|
filedata[i] = line
|
||||||
writefile(FILE, filedata)
|
writefile(FILE, filedata)
|
||||||
if runtool():
|
if runtool(filedata):
|
||||||
print('pass')
|
print('pass')
|
||||||
writefile(BACKUPFILE, filedata)
|
writefile(BACKUPFILE, filedata)
|
||||||
return True
|
return True
|
||||||
|
@ -94,7 +118,7 @@ def replaceandrun2(what, filedata, i, line1, line2):
|
||||||
filedata[i] = line1
|
filedata[i] = line1
|
||||||
filedata[i + 1] = line2
|
filedata[i + 1] = line2
|
||||||
writefile(FILE, filedata)
|
writefile(FILE, filedata)
|
||||||
if runtool():
|
if runtool(filedata):
|
||||||
print('pass')
|
print('pass')
|
||||||
writefile(BACKUPFILE, filedata)
|
writefile(BACKUPFILE, filedata)
|
||||||
else:
|
else:
|
||||||
|
@ -111,7 +135,7 @@ def clearandrun(what, filedata, i1, i2):
|
||||||
filedata2[i] = ''
|
filedata2[i] = ''
|
||||||
i = i + 1
|
i = i + 1
|
||||||
writefile(FILE, filedata2)
|
writefile(FILE, filedata2)
|
||||||
if runtool():
|
if runtool(filedata2):
|
||||||
print('pass')
|
print('pass')
|
||||||
writefile(BACKUPFILE, filedata2)
|
writefile(BACKUPFILE, filedata2)
|
||||||
return filedata2
|
return filedata2
|
||||||
|
@ -249,15 +273,19 @@ def removeline(filedata):
|
||||||
|
|
||||||
# reduce..
|
# reduce..
|
||||||
print('Make sure error can be reproduced...')
|
print('Make sure error can be reproduced...')
|
||||||
|
elapsed_time = None
|
||||||
|
t = time.perf_counter()
|
||||||
if not runtool():
|
if not runtool():
|
||||||
print("Cannot reproduce")
|
print("Cannot reproduce")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
elapsed_time = time.perf_counter() - t
|
||||||
|
print('elapsed_time: {}'.format(elapsed_time))
|
||||||
|
|
||||||
f = open(FILE, 'rt')
|
f = open(FILE, 'rt')
|
||||||
filedata = f.readlines()
|
filedata = f.readlines()
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
writefile(BACKUPFILE, filedata)
|
writefile(ORGFILE, filedata)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
filedata1 = list(filedata)
|
filedata1 = list(filedata)
|
||||||
|
|
Loading…
Reference in New Issue