#!/usr/bin/env python
"""Calls C-Reduce to create a minimal reproducer for clang crashes.

Output files:
  *.reduced.sh -- crash reproducer with minimal arguments
  *.reduced.cpp -- the reduced file
  *.test.sh -- interestingness test for C-Reduce
"""

from __future__ import print_function
from argparse import ArgumentParser, RawTextHelpFormatter
import os
import re
import stat
import sys
import subprocess
import pipes
import shlex
import tempfile
import shutil
from distutils.spawn import find_executable

verbose = False
creduce_cmd = None
clang_cmd = None
not_cmd = None

def verbose_print(*args, **kwargs):
  if verbose:
    print(*args, **kwargs)

def check_file(fname):
  if not os.path.isfile(fname):
    sys.exit("ERROR: %s does not exist" % (fname))
  return fname

def check_cmd(cmd_name, cmd_dir, cmd_path=None):
  """
  Returns absolute path to cmd_path if it is given,
  or absolute path to cmd_dir/cmd_name.
  """
  if cmd_path:
    cmd = find_executable(cmd_path)
    if cmd:
      return cmd
    sys.exit("ERROR: executable `%s` not found" % (cmd_path))

  cmd = find_executable(cmd_name, path=cmd_dir)
  if cmd:
    return cmd

  if not cmd_dir:
    cmd_dir = "$PATH"
  sys.exit("ERROR: `%s` not found in %s" % (cmd_name, cmd_dir))

def quote_cmd(cmd):
  return ' '.join(pipes.quote(arg) for arg in cmd)

def write_to_script(text, filename):
  with open(filename, 'w') as f:
    f.write(text)
  os.chmod(filename, os.stat(filename).st_mode | stat.S_IEXEC)

class Reduce(object):
  def __init__(self, crash_script, file_to_reduce):
    crash_script_name, crash_script_ext = os.path.splitext(crash_script)
    file_reduce_name, file_reduce_ext = os.path.splitext(file_to_reduce)

    self.testfile = file_reduce_name + '.test.sh'
    self.crash_script = crash_script_name + '.reduced' + crash_script_ext
    self.file_to_reduce = file_reduce_name + '.reduced' + file_reduce_ext
    shutil.copy(file_to_reduce, self.file_to_reduce)

    self.clang = clang_cmd
    self.clang_args = []
    self.expected_output = []
    self.is_crash = True
    self.creduce_flags = ["--tidy"]

    self.read_clang_args(crash_script, file_to_reduce)
    self.read_expected_output()

  def get_crash_cmd(self, cmd=None, args=None, filename=None):
    if not cmd:
      cmd = self.clang
    if not args:
      args = self.clang_args
    if not filename:
      filename = self.file_to_reduce

    return [cmd] + args + [filename]

  def read_clang_args(self, crash_script, filename):
    print("\nReading arguments from crash script...")
    with open(crash_script) as f:
      # Assume clang call is the first non comment line.
      cmd = []
      for line in f:
        if not line.lstrip().startswith('#'):
          cmd = shlex.split(line)
          break
    if not cmd:
      sys.exit("Could not find command in the crash script.");

    # Remove clang and filename from the command
    # Assume the last occurrence of the filename is the clang input file
    del cmd[0]
    for i in range(len(cmd)-1, -1, -1):
      if cmd[i] == filename:
        del cmd[i]
        break
    self.clang_args = cmd
    verbose_print("Clang arguments:", quote_cmd(self.clang_args))

  def read_expected_output(self):
    print("\nGetting expected crash output...")
    p = subprocess.Popen(self.get_crash_cmd(),
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    crash_output, _ = p.communicate()
    result = []

    # Remove color codes
    ansi_escape = r'\x1b\[[0-?]*m'
    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 ceclaration '(.+)'",
               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)
        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,
    # ignoring some common functions
    # 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:
      stacktrace_re = r'[0-9]+\s+0[xX][0-9a-fA-F]+\s*([^(]+)\('
      filters = ["PrintStackTraceSignalHandler",
                 "llvm::sys::RunSignalHandlers",
                 "SignalHandler", "__restore_rt", "gsignal", "abort"]
      matches = re.findall(stacktrace_re, crash_output)
      result = [x for x in matches if x and x.strip() not in filters][:5]
      for msg in result:
        print("Found stack trace function:", msg)

    if not result:
      print("ERROR: no crash was found")
      print("The crash output was:\n========\n%s========" % crash_output)
      sys.exit(1)

    self.expected_output = result

  def check_expected_output(self, args=None, filename=None):
    if not args:
      args = self.clang_args
    if not filename:
      filename = self.file_to_reduce

    p = subprocess.Popen(self.get_crash_cmd(args=args, filename=filename),
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    crash_output, _ = p.communicate()
    return all(msg in crash_output.decode('utf-8') for msg in
               self.expected_output)

  def write_interestingness_test(self):
    print("\nCreating the interestingness test...")

    crash_flag = "--crash" if self.is_crash else ""

    output = "#!/bin/bash\n%s %s %s >& t.log || exit 1\n" % \
        (pipes.quote(not_cmd), crash_flag, quote_cmd(self.get_crash_cmd()))

    for msg in self.expected_output:
      output += 'grep -F %s t.log || exit 1\n' % pipes.quote(msg)

    write_to_script(output, self.testfile)
    self.check_interestingness()

  def check_interestingness(self):
    testfile = os.path.abspath(self.testfile)

    # Check that the test considers the original file interesting
    with open(os.devnull, 'w') as devnull:
      returncode = subprocess.call(testfile, stdout=devnull)
    if returncode:
      sys.exit("The interestingness test does not pass for the original file.")

    # Check that an empty file is not interesting
    # Instead of modifying the filename in the test file, just run the command
    with tempfile.NamedTemporaryFile() as empty_file:
      is_interesting = self.check_expected_output(filename=empty_file.name)
    if is_interesting:
      sys.exit("The interestingness test passes for an empty file.")

  def clang_preprocess(self):
    print("\nTrying to preprocess the source file...")
    with tempfile.NamedTemporaryFile() as tmpfile:
      cmd_preprocess = self.get_crash_cmd() + ['-E', '-o', tmpfile.name]
      cmd_preprocess_no_lines = cmd_preprocess + ['-P']
      try:
        subprocess.check_call(cmd_preprocess_no_lines)
        if self.check_expected_output(filename=tmpfile.name):
          print("Successfully preprocessed with line markers removed")
          shutil.copy(tmpfile.name, self.file_to_reduce)
        else:
          subprocess.check_call(cmd_preprocess)
          if self.check_expected_output(filename=tmpfile.name):
            print("Successfully preprocessed without removing line markers")
            shutil.copy(tmpfile.name, self.file_to_reduce)
          else:
            print("No longer crashes after preprocessing -- "
                  "using original source")
      except subprocess.CalledProcessError:
        print("Preprocessing failed")

  @staticmethod
  def filter_args(args, opts_equal=[], opts_startswith=[],
                  opts_one_arg_startswith=[]):
    result = []
    skip_next = False
    for arg in args:
      if skip_next:
        skip_next = False
        continue
      if any(arg == a for a in opts_equal):
        continue
      if any(arg.startswith(a) for a in opts_startswith):
        continue
      if any(arg.startswith(a) for a in opts_one_arg_startswith):
        skip_next = True
        continue
      result.append(arg)
    return result

  def try_remove_args(self, args, msg=None, extra_arg=None, **kwargs):
    new_args = self.filter_args(args, **kwargs)

    if extra_arg:
      if extra_arg in new_args:
        new_args.remove(extra_arg)
      new_args.append(extra_arg)

    if (new_args != args and
        self.check_expected_output(args=new_args)):
      if msg:
        verbose_print(msg)
      return new_args
    return args

  def try_remove_arg_by_index(self, args, index):
    new_args = args[:index] + args[index+1:]
    removed_arg = args[index]

    # Heuristic for grouping arguments:
    # remove next argument if it doesn't start with "-"
    if index < len(new_args) and not new_args[index].startswith('-'):
      del new_args[index]
      removed_arg += ' ' + args[index+1]

    if self.check_expected_output(args=new_args):
      verbose_print("Removed", removed_arg)
      return new_args, index
    return args, index+1

  def simplify_clang_args(self):
    """Simplify clang arguments before running C-Reduce to reduce the time the
    interestingness test takes to run.
    """
    print("\nSimplifying the clang command...")

    # Remove some clang arguments to speed up the interestingness test
    new_args = self.clang_args
    new_args = self.try_remove_args(new_args,
                                    msg="Removed debug info options",
                                    opts_startswith=["-gcodeview",
                                                     "-debug-info-kind=",
                                                     "-debugger-tuning="])

    new_args = self.try_remove_args(new_args,
                                    msg="Removed --show-includes",
                                    opts_startswith=["--show-includes"])
    # Not suppressing warnings (-w) sometimes prevents the crash from occurring
    # after preprocessing
    new_args = self.try_remove_args(new_args,
                                    msg="Replaced -W options with -w",
                                    extra_arg='-w',
                                    opts_startswith=["-W"])
    new_args = self.try_remove_args(new_args,
                                    msg="Replaced optimization level with -O0",
                                    extra_arg="-O0",
                                    opts_startswith=["-O"])

    # Try to remove compilation steps
    new_args = self.try_remove_args(new_args, msg="Added -emit-llvm",
                                    extra_arg="-emit-llvm")
    new_args = self.try_remove_args(new_args, msg="Added -fsyntax-only",
                                    extra_arg="-fsyntax-only")

    # Try to make implicit int an error for more sensible test output
    new_args = self.try_remove_args(new_args, msg="Added -Werror=implicit-int",
                                    opts_equal=["-w"],
                                    extra_arg="-Werror=implicit-int")

    self.clang_args = new_args
    verbose_print("Simplified command:", quote_cmd(self.get_crash_cmd()))

  def reduce_clang_args(self):
    """Minimize the clang arguments after running C-Reduce, to get the smallest
    command that reproduces the crash on the reduced file.
    """
    print("\nReducing the clang crash command...")

    new_args = self.clang_args

    # Remove some often occurring args
    new_args = self.try_remove_args(new_args, msg="Removed -D options",
                                    opts_startswith=["-D"])
    new_args = self.try_remove_args(new_args, msg="Removed -D options",
                                    opts_one_arg_startswith=["-D"])
    new_args = self.try_remove_args(new_args, msg="Removed -I options",
                                    opts_startswith=["-I"])
    new_args = self.try_remove_args(new_args, msg="Removed -I options",
                                    opts_one_arg_startswith=["-I"])
    new_args = self.try_remove_args(new_args, msg="Removed -W options",
                                    opts_startswith=["-W"])

    # Remove other cases that aren't covered by the heuristic
    new_args = self.try_remove_args(new_args, msg="Removed -mllvm",
                                    opts_one_arg_startswith=["-mllvm"])

    i = 0
    while i < len(new_args):
      new_args, i = self.try_remove_arg_by_index(new_args, i)

    self.clang_args = new_args

    reduced_cmd = quote_cmd(self.get_crash_cmd())
    write_to_script(reduced_cmd, self.crash_script)
    print("Reduced command:", reduced_cmd)

  def run_creduce(self):
    print("\nRunning C-Reduce...")
    try:
      p = subprocess.Popen([creduce_cmd] + self.creduce_flags +
                           [self.testfile, self.file_to_reduce])
      p.communicate()
    except KeyboardInterrupt:
      # Hack to kill C-Reduce because it jumps into its own pgid
      print('\n\nctrl-c detected, killed creduce')
      p.kill()

def main():
  global verbose
  global creduce_cmd
  global clang_cmd
  global not_cmd

  parser = ArgumentParser(description=__doc__,
                          formatter_class=RawTextHelpFormatter)
  parser.add_argument('crash_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('--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.")
  parser.add_argument('--creduce', dest='creduce', type=str,
                      help="The path to the `creduce` executable. "
                      "Required if `creduce` is not in PATH environment.")
  parser.add_argument('-v', '--verbose', action='store_true')
  args = parser.parse_args()

  verbose = args.verbose
  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])

  r = Reduce(crash_script, file_to_reduce)

  r.simplify_clang_args()
  r.write_interestingness_test()
  r.clang_preprocess()
  r.run_creduce()
  r.reduce_clang_args()

if __name__ == '__main__':
  main()
