[clang] 0c80b54 - Some updates/fixes to the creduce script.
Amy Huang via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 12 13:40:44 PST 2020
Author: Amy Huang
Date: 2020-11-12T13:40:26-08:00
New Revision: 0c80b542d38b4819809c600e71a6997a9b4e4294
URL: https://github.com/llvm/llvm-project/commit/0c80b542d38b4819809c600e71a6997a9b4e4294
DIFF: https://github.com/llvm/llvm-project/commit/0c80b542d38b4819809c600e71a6997a9b4e4294.diff
LOG: Some updates/fixes to the creduce script.
This was motivated by changes to llvm's `not --crash` disabling symbolization
but I ended up removing `not` from the script entirely because it
returns differently depending on whether clang "crashes" or exits for some
other reason. The script had to choose between calling `not` and `not --crash`
and sometimes it was wrong.
The script also now disables symbolization when we don't read the stack
trace because symbolizing is kind of slow.
Differential Revision: https://reviews.llvm.org/D91372
Added:
Modified:
clang/utils/creduce-clang-crash.py
Removed:
################################################################################
diff --git a/clang/utils/creduce-clang-crash.py b/clang/utils/creduce-clang-crash.py
index b69d6efc2481..cdc639c6f854 100755
--- a/clang/utils/creduce-clang-crash.py
+++ b/clang/utils/creduce-clang-crash.py
@@ -23,7 +23,6 @@
verbose = False
creduce_cmd = None
clang_cmd = None
-not_cmd = None
def verbose_print(*args, **kwargs):
if verbose:
@@ -77,7 +76,7 @@ def __init__(self, crash_script, file_to_reduce):
self.clang = clang_cmd
self.clang_args = []
self.expected_output = []
- self.is_crash = True
+ self.needs_stack_trace = False
self.creduce_flags = ["--tidy"]
self.read_clang_args(crash_script, file_to_reduce)
@@ -128,23 +127,20 @@ def read_expected_output(self):
crash_output = re.sub(ansi_escape, '', crash_output.decode('utf-8'))
# Look for specific error messages
- regexes = [r"Assertion `(.+)' failed", # Linux assert()
- r"Assertion failed: (.+),", # FreeBSD/Mac assert()
- r"fatal error: error in backend: (.+)",
- r"LLVM ERROR: (.+)",
- r"UNREACHABLE executed (at .+)?!",
- r"LLVM IR generation of declaration '(.+)'",
- r"Generating code for declaration '(.+)'",
- r"\*\*\* Bad machine code: (.+) \*\*\*"]
+ regexes = [r"Assertion .+ failed", # Linux assert()
+ r"Assertion failed: .+,", # FreeBSD/Mac assert()
+ r"fatal error: error in backend: .+",
+ r"LLVM ERROR: .+",
+ r"UNREACHABLE executed at .+?!",
+ r"LLVM IR generation of declaration '.+'",
+ r"Generating code for declaration '.+'",
+ r"\*\*\* Bad machine code: .+ \*\*\*"]
for msg_re in regexes:
match = re.search(msg_re, crash_output)
if match:
- msg = match.group(1)
+ msg = match.group(0)
result = [msg]
print("Found message:", msg)
-
- if "fatal error:" in msg_re:
- self.is_crash = False
break
# If no message was found, use the top five stack trace functions,
@@ -152,12 +148,15 @@ def read_expected_output(self):
# Five is a somewhat arbitrary number; the goal is to get a small number
# of identifying functions with some leeway for common functions
if not result:
+ self.needs_stack_trace = True
stacktrace_re = r'[0-9]+\s+0[xX][0-9a-fA-F]+\s*([^(]+)\('
- filters = ["PrintStackTraceSignalHandler",
- "llvm::sys::RunSignalHandlers",
- "SignalHandler", "__restore_rt", "gsignal", "abort"]
+ filters = ["PrintStackTrace", "RunSignalHandlers", "CleanupOnSignal",
+ "HandleCrash", "SignalHandler", "__restore_rt", "gsignal", "abort"]
+ def skip_function(func_name):
+ return any(name in func_name for name in filters)
+
matches = re.findall(stacktrace_re, crash_output)
- result = [x for x in matches if x and x.strip() not in filters][:5]
+ result = [x for x in matches if x and not skip_function(x)][:5]
for msg in result:
print("Found stack trace function:", msg)
@@ -184,10 +183,17 @@ def check_expected_output(self, args=None, filename=None):
def write_interestingness_test(self):
print("\nCreating the interestingness test...")
- crash_flag = "--crash" if self.is_crash else ""
+ # Disable symbolization if it's not required to avoid slow symbolization.
+ disable_symbolization = ''
+ if not self.needs_stack_trace:
+ disable_symbolization = 'export LLVM_DISABLE_SYMBOLIZATION=1'
- output = "#!/bin/bash\n%s %s %s >& t.log || exit 1\n" % \
- (pipes.quote(not_cmd), crash_flag, quote_cmd(self.get_crash_cmd()))
+ output = """#!/bin/bash
+%s
+if %s >& t.log ; then
+ exit 1
+fi
+""" % (disable_symbolization, quote_cmd(self.get_crash_cmd()))
for msg in self.expected_output:
output += 'grep -F %s t.log || exit 1\n' % pipes.quote(msg)
@@ -372,7 +378,6 @@ def main():
global verbose
global creduce_cmd
global clang_cmd
- global not_cmd
parser = ArgumentParser(description=__doc__,
formatter_class=RawTextHelpFormatter)
@@ -382,9 +387,6 @@ def main():
help="Name of the file to be reduced.")
parser.add_argument('--llvm-bin', dest='llvm_bin', type=str,
help="Path to the LLVM bin directory.")
- parser.add_argument('--llvm-not', dest='llvm_not', type=str,
- help="The path to the `not` executable. "
- "By default uses the llvm-bin directory.")
parser.add_argument('--clang', dest='clang', type=str,
help="The path to the `clang` executable. "
"By default uses the llvm-bin directory.")
@@ -398,7 +400,6 @@ def main():
llvm_bin = os.path.abspath(args.llvm_bin) if args.llvm_bin else None
creduce_cmd = check_cmd('creduce', None, args.creduce)
clang_cmd = check_cmd('clang', llvm_bin, args.clang)
- not_cmd = check_cmd('not', llvm_bin, args.llvm_not)
crash_script = check_file(args.crash_script[0])
file_to_reduce = check_file(args.file_to_reduce[0])
More information about the cfe-commits
mailing list