akhuang created this revision.
akhuang added reviewers: rnk, george.burgess.iv.
Herald added a reviewer: serge-sans-paille.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Add a script that calls C-Reduce on an input file and given the clang crash
script, which is used to generate an interestingness test for C-Reduce.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D59118
Files:
.arcconfig
clang/utils/creduce-clang-crash.py
Index: clang/utils/creduce-clang-crash.py
===================================================================
--- /dev/null
+++ clang/utils/creduce-clang-crash.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+# A tool that calls C-Reduce to create a minimal reproducer for clang crashes
+# Requires C-Reduce and not (part of LLVM utils) to be installed
+
+from argparse import ArgumentParser
+import os
+import re
+import stat
+import sys
+import subprocess
+
+def is_exe(fpath):
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+def which(program):
+ """
+ Return 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 create_test(build_script, llvm_not):
+ """
+ Create an interestingness test from the crash output.
+ Return as a string.
+ """
+ # Get clang call from build script
+ cmd = None
+ with open(build_script, 'r') as f:
+ cmd = f.read()
+ cmd = re.sub("#!.*\n", "", cmd)
+ cmd = cmd.rstrip('\n\r')
+
+ # Get crash output
+ p = subprocess.Popen(build_script,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ crash_output, _ = p.communicate()
+
+ output = ['#!/bin/bash']
+ output.append('%s --crash %s >& t.log || exit 1' % (llvm_not, cmd))
+
+ # Add messages from crash output to the test
+ # If there is an Assertion failure, use that; otherwise use the
+ # last five stack trace functions
+ assertion_re = "Assertion \`([^\']+)\' failed"
+ assertion_match = re.search(assertion_re, crash_output)
+ if assertion_match:
+ msg = assertion_match.group(1).replace('"', '\\"')
+ output.append('grep "%s" t.log || exit 1' % msg)
+ else:
+ stacktrace_re = "#[0-9]+\s+0[xX][0-9a-fA-F]+\s*([^(]+)\("
+ matches = re.findall(stacktrace_re, crash_output)
+ del matches[:len(matches)-5]
+ output += ['grep "%s" t.log || exit 1' % msg for msg in matches]
+
+ return output
+
+def main():
+ parser = ArgumentParser(description='Runs C-Reduce on the input file')
+ parser.add_argument('build_script', type=str, nargs=1,
+ help='Name of the script that generates the crash.')
+ parser.add_argument('file_to_reduce', type=str, nargs=1,
+ help='Name of the file to be reduced.')
+ parser.add_argument('-o', '--output', dest='output', type=str,
+ help='Name of the output file for the reduction. Optional.')
+ parser.add_argument('--llvm-not', dest='llvm_not', type=str,
+ help="""The path to the llvm-not executable.
+ Required if 'not' is not in PATH environment.""");
+ parser.add_argument('--creduce', dest='creduce', type=str,
+ help="""The path to the C-Reduce executable.
+ Required if 'creduce' is not in PATH environment.""");
+ args = parser.parse_args()
+
+ build_script = os.path.abspath(args.build_script[0])
+ file_to_reduce = os.path.abspath(args.file_to_reduce[0])
+ llvm_not = which(args.llvm_not) if args.llvm_not else which('not')
+ creduce = which(args.creduce) if args.creduce else which('creduce')
+
+ if not os.path.isfile(build_script):
+ print(("ERROR: input file '%s' does not exist") % build_script)
+ sys.exit(1)
+
+ if not os.path.isfile(file_to_reduce):
+ print(("ERROR: input file '%s' does not exist") % file_to_reduce)
+ sys.exit(1)
+
+ if not llvm_not:
+ parser.print_help()
+ sys.exit(1)
+
+ if not creduce:
+ parser.print_help()
+ sys.exit(1)
+
+ # Write interestingness test to file
+ test_contents = create_test(build_script, llvm_not)
+ testname, _ = os.path.splitext(file_to_reduce)
+ testfile = testname + '.test.sh'
+ open(testfile, 'w').write('\n'.join(test_contents))
+ os.chmod(testfile, os.stat(testfile).st_mode | stat.S_IEXEC)
+
+ # Call C-Reduce
+ try:
+ p = subprocess.Popen([creduce, testfile, file_to_reduce])
+ p.communicate()
+
+ except KeyboardInterrupt:
+ print('\n\nctrl-c detected, killed creduce')
+ p.kill()
+
+ sys.exit(0)
+
+if __name__ == '__main__':
+ main()
Index: .arcconfig
===================================================================
--- .arcconfig
+++ .arcconfig
@@ -1,4 +1,4 @@
{
- "repository.callsign" : "G",
- "conduit_uri" : "https://reviews.llvm.org/"
+ "repository.callsign" : "G",
+ "conduit_uri" : "https://reviews.llvm.org/"
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits