#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import print_function

usage = """%prog: A test for OOM conditions in the shell.

%prog finds segfaults and other errors caused by incorrect handling of
allocation during OOM (out-of-memory) conditions.
"""

help = """Check for regressions only. This runs a set of files with a known
number of OOM errors (specified by REGRESSION_COUNT), and exits with a non-zero
result if more or less errors are found. See js/src/Makefile.in for invocation.
"""


import hashlib
import re
import shlex
import subprocess
import sys
import threading
import time

from optparse import OptionParser

#####################################################################
# Utility functions
#####################################################################
def run(args, stdin=None):
  class ThreadWorker(threading.Thread):
    def __init__(self, pipe):
      super(ThreadWorker, self).__init__()
      self.all = ""
      self.pipe = pipe
      self.setDaemon(True)

    def run(self):
      while True:
        line = self.pipe.readline()
        if line == '': break
        else:
          self.all += line

  try:
    if type(args) == str:
      args = shlex.split(args)

    args = [str(a) for a in args] # convert to strs

    stdin_pipe = subprocess.PIPE if stdin else None
    proc = subprocess.Popen(args, stdin=stdin_pipe, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    if stdin_pipe:
      proc.stdin.write(stdin)
      proc.stdin.close()

    stdout_worker = ThreadWorker(proc.stdout)
    stderr_worker = ThreadWorker(proc.stderr)
    stdout_worker.start()
    stderr_worker.start()

    proc.wait()
    stdout_worker.join()
    stderr_worker.join()

  except KeyboardInterrupt as e:
    sys.exit(-1)

  stdout, stderr = stdout_worker.all, stderr_worker.all
  result = (stdout, stderr, proc.returncode)
  return result

def get_js_files():
  (out, err, exit) = run('find ../jit-test/tests -name "*.js"')
  if (err, exit) != ("", 0):
    sys.exit("Wrong directory, run from an objdir")
  return out.split()



#####################################################################
# Blacklisting
#####################################################################
def in_blacklist(sig):
  return sig in blacklist

def add_to_blacklist(sig):
  blacklist[sig] = blacklist.get(sig, 0)
  blacklist[sig] += 1

# How often is a particular lines important for this.
def count_lines():
  """Keep track of the amount of times individual lines occur, in order to
     prioritize the errors which occur most frequently."""
  counts = {}
  for string,count in blacklist.items():
    for line in string.split("\n"):
      counts[line] = counts.get(line, 0) + count

  lines = []
  for k,v in counts.items():
    lines.append("{0:6}: {1}".format(v, k))

  lines.sort()

  countlog = file("../OOM_count_log", "w")
  countlog.write("\n".join(lines))
  countlog.flush()
  countlog.close()


#####################################################################
# Output cleaning
#####################################################################
def clean_voutput(err):
  # Skip what we can't reproduce
  err = re.sub(r"^--\d+-- run: /usr/bin/dsymutil \"shell/js\"$", "", err, flags=re.MULTILINE)
  err = re.sub(r"^==\d+==", "", err, flags=re.MULTILINE)
  err = re.sub(r"^\*\*\d+\*\*", "", err, flags=re.MULTILINE)
  err = re.sub(r"^\s+by 0x[0-9A-Fa-f]+: ", "by: ", err, flags=re.MULTILINE)
  err = re.sub(r"^\s+at 0x[0-9A-Fa-f]+: ", "at: ", err, flags=re.MULTILINE)
  err = re.sub(r"(^\s+Address 0x)[0-9A-Fa-f]+( is not stack'd)", r"\1\2", err, flags=re.MULTILINE)
  err = re.sub(r"(^\s+Invalid write of size )\d+", r"\1x", err, flags=re.MULTILINE)
  err = re.sub(r"(^\s+Invalid read of size )\d+", r"\1x", err, flags=re.MULTILINE)
  err = re.sub(r"(^\s+Address 0x)[0-9A-Fa-f]+( is )\d+( bytes inside a block of size )[0-9,]+( free'd)", r"\1\2\3\4", err, flags=re.MULTILINE)

  # Skip the repeating bit due to the segfault
  lines = []
  for l in err.split('\n'):
    if l == " Process terminating with default action of signal 11 (SIGSEGV)":
      break
    lines.append(l)
  err = '\n'.join(lines)

  return err

def remove_failed_allocation_backtraces(err):
  lines = []

  add = True
  for l in err.split('\n'):

    # Set start and end conditions for including text
    if l == " The site of the failed allocation is:":
      add = False
    elif l[:2] not in ['by: ', 'at:']:
      add = True

    if add:
      lines.append(l)


  err = '\n'.join(lines)

  return err


def clean_output(err):
  err = re.sub(r"^js\(\d+,0x[0-9a-f]+\) malloc: \*\*\* error for object 0x[0-9a-f]+: pointer being freed was not allocated\n\*\*\* set a breakppoint in malloc_error_break to debug\n$", "pointer being freed was not allocated", err, flags=re.MULTILINE)

  return err


#####################################################################
# Consts, etc
#####################################################################

command_template = 'shell/js' \
                 + ' -m -j -p' \
                 + ' -e "const platform=\'darwin\'; const libdir=\'../jit-test/lib/\';"' \
                 + ' -f ../jit-test/lib/prolog.js' \
                 + ' -f {0}'


# Blacklists are things we don't want to see in our logs again (though we do
# want to count them when they happen). Whitelists we do want to see in our
# logs again, principally because the information we have isn't enough.

blacklist = {}
add_to_blacklist(r"('', '', 1)") # 1 means OOM if the shell hasn't launched yet.
add_to_blacklist(r"('', 'out of memory\n', 1)")

whitelist = set()
whitelist.add(r"('', 'out of memory\n', -11)") # -11 means OOM
whitelist.add(r"('', 'out of memory\nout of memory\n', -11)")



#####################################################################
# Program
#####################################################################

# Options
parser = OptionParser(usage=usage)
parser.add_option("-r", "--regression", action="store", metavar="REGRESSION_COUNT", help=help,
                  type="int", dest="regression", default=None)
                  
(OPTIONS, args) = parser.parse_args()


if OPTIONS.regression != None:
  # TODO: This should be expanded as we get a better hang of the OOM problems.
  # For now, we'll just check that the number of OOMs in one short file does not
  # increase.
  files = ["../jit-test/tests/arguments/args-createontrace.js"]
else:
  files = get_js_files()

  # Use a command-line arg to reduce the set of files
  if len (args):
    files = [f for f in files if f.find(args[0]) != -1]


if OPTIONS.regression == None:
  # Don't use a logfile, this is automated for tinderbox.
  log = file("../OOM_log", "w")


num_failures = 0
for f in files:

  # Run it once to establish boundaries
  command = (command_template + ' -O').format(f)
  out, err, exit = run(command)
  max = re.match(".*OOM max count: (\d+).*", out, flags=re.DOTALL).groups()[0]
  max = int(max)
  
  # OOMs don't recover well for the first 20 allocations or so.
  # TODO: revisit this.
  for i in range(20, max): 

    if OPTIONS.regression == None:
      print("Testing allocation {0}/{1} in {2}".format(i,max,f))
    else:
      sys.stdout.write('.') # something short for tinderbox, no space or \n

    command = (command_template + ' -A {0}').format(f, i)
    out, err, exit = run(command)

    # Success (5 is SM's exit code for controlled errors)
    if exit == 5 and err.find("out of memory") != -1:
      continue

    # Failure
    else:

      if OPTIONS.regression != None:
        # Just count them
        num_failures += 1
        continue

      #########################################################################
      # The regression tests ends above. The rest of this is for running  the
      # script manually.
      #########################################################################

      problem = str((out, err, exit))
      if in_blacklist(problem) and problem not in whitelist:
        add_to_blacklist(problem)
        continue

      add_to_blacklist(problem)


      # Get valgrind output for a good stack trace
      vcommand = "valgrind --dsymutil=yes -q --log-file=OOM_valgrind_log_file " + command
      run(vcommand)
      vout = file("OOM_valgrind_log_file").read()
      vout = clean_voutput(vout)
      sans_alloc_sites = remove_failed_allocation_backtraces(vout)

      # Don't print duplicate information
      if in_blacklist(sans_alloc_sites):
        add_to_blacklist(sans_alloc_sites)
        continue

      add_to_blacklist(sans_alloc_sites)

      log.write ("\n")
      log.write ("\n")
      log.write ("=========================================================================")
      log.write ("\n")
      log.write ("An allocation failure at\n\tallocation {0}/{1} in {2}\n\t"
                 "causes problems (detected using bug 624094)"
                 .format(i, max, f))
      log.write ("\n")
      log.write ("\n")

      log.write ("Command (from obj directory, using patch from bug 624094):\n  " + command)
      log.write ("\n")
      log.write ("\n")
      log.write ("stdout, stderr, exitcode:\n  " + problem)
      log.write ("\n")
      log.write ("\n")

      double_free = err.find("pointer being freed was not allocated") != -1
      oom_detected = err.find("out of memory") != -1
      multiple_oom_detected = err.find("out of memory\nout of memory") != -1
      segfault_detected = exit == -11

      log.write ("Diagnosis: ")
      log.write ("\n")
      if multiple_oom_detected:
        log.write ("  - Multiple OOMs reported")
        log.write ("\n")
      if segfault_detected:
        log.write ("  - segfault")
        log.write ("\n")
      if not oom_detected:
        log.write ("  - No OOM checking")
        log.write ("\n")
      if double_free:
        log.write ("  - Double free")
        log.write ("\n")

      log.write ("\n")

      log.write ("Valgrind info:\n" + vout)
      log.write ("\n")
      log.write ("\n")
      log.flush()

  if OPTIONS.regression == None:
    count_lines()

print()

# Do the actual regression check
if OPTIONS.regression != None:
  expected_num_failures = OPTIONS.regression

  if num_failures != expected_num_failures:

    print("TEST-UNEXPECTED-FAIL |", end='')
    if num_failures > expected_num_failures:
      print("More out-of-memory errors were found ({0}) than expected ({1}). "
            "This probably means an allocation site has been added without a "
            "NULL-check. If this is unavoidable, you can account for it by "
            "updating Makefile.in.".format(num_failures, expected_num_failures),
            end='')
    else:
      print("Congratulations, you have removed {0} out-of-memory error(s) "
            "({1} remain)! Please account for it by updating Makefile.in." 
            .format(expected_num_failures - num_failures, num_failures),
            end='')
    sys.exit(-1)
  else:
    print('TEST-PASS | find_OOM_errors | Found the expected number of OOM '
          'errors ({0})'.format(expected_num_failures))

