def interesting(cliArgs, tempPrefix): (timeout, aArgs, bArgs, args) = parseOptions(cliArgs) aRuninfo = timedRun.timed_run(args[:1] + aArgs + args[1:], timeout, tempPrefix + "-a") bRuninfo = timedRun.timed_run(args[:1] + bArgs + args[1:], timeout, tempPrefix + "-b") timeString = " (1st Run: %.3f seconds) (2nd Run: %.3f seconds)" % ( aRuninfo.elapsedtime, bRuninfo.elapsedtime) if aRuninfo.sta != timedRun.TIMED_OUT and bRuninfo.sta != timedRun.TIMED_OUT: if aRuninfo.rc != bRuninfo.rc: print("[Interesting] Different return code. (%d, %d) " % (aRuninfo.rc, bRuninfo.rc)) + timeString return True if not filecmp.cmp(aRuninfo.out, bRuninfo.out): print "[Interesting] Different output. " + timeString return True if not filecmp.cmp(aRuninfo.err, bRuninfo.err): print "[Interesting] Different error output. " + timeString return True else: print "[Uninteresting] At least one test timed out." + timeString return False print "[Uninteresting] Identical behaviour." + timeString return False
def interesting(cliArgs, tempPrefix): (regexEnabled, crashSig, timeout, args) = parseOptions(cliArgs) # Examine stack for crash signature, this is needed if crashSig is specified. runinfo = timedRun.timed_run(args, timeout, tempPrefix) if runinfo.sta == timedRun.CRASHED: sps.grabCrashLog(args[0], runinfo.pid, tempPrefix, True) timeString = " (%.3f seconds)" % runinfo.elapsedtime crashLogName = tempPrefix + "-crash.txt" if runinfo.sta == timedRun.CRASHED: if os.path.exists(crashLogName): # When using this script, remember to escape characters, e.g. "\(" instead of "(" ! found, _foundSig = fileIngredients.fileContains( crashLogName, crashSig, regexEnabled) if found: print 'Exit status: ' + runinfo.msg + timeString return True else: print "[Uninteresting] It crashed somewhere else!" + timeString return False else: print "[Uninteresting] It appeared to crash, but no crash log was found?" + timeString return False else: print "[Uninteresting] It didn't crash." + timeString return False
def interesting(cliArgs, tempPrefix): (regexEnabled, crashSig, timeout, args) = parseOptions(cliArgs) # Examine stack for crash signature, this is needed if crashSig is specified. runinfo = timedRun.timed_run(args, timeout, tempPrefix) if runinfo.sta == timedRun.CRASHED: sps.grabCrashLog(args[0], runinfo.pid, tempPrefix, True) timeString = " (%.3f seconds)" % runinfo.elapsedtime crashLogName = tempPrefix + "-crash.txt" if runinfo.sta == timedRun.CRASHED: if os.path.exists(crashLogName): # When using this script, remember to escape characters, e.g. "\(" instead of "(" ! found, _foundSig = fileIngredients.fileContains(crashLogName, crashSig, regexEnabled) if found: print 'Exit status: ' + runinfo.msg + timeString return True else: print "[Uninteresting] It crashed somewhere else!" + timeString return False else: print "[Uninteresting] It appeared to crash, but no crash log was found?" + timeString return False else: print "[Uninteresting] It didn't crash." + timeString return False
def interesting(args, tempPrefix): timeout = int(args[0]) runinfo = timedRun.timed_run(args[1:], timeout, tempPrefix) if runinfo.sta == timedRun.TIMED_OUT: return True else: print "Exited in %.3f seconds" % runinfo.elapsedtime return False
def interesting(args, tempPrefix): timeout = int(args[0]) returncode = subprocess.call([jsshell, "-c", args[1]], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if returncode != 0: print "JS didn't compile, skipping browser test" return False wantStack = False # We do not care about the stack when using this interestingness test. runinfo = timedRun.timed_run(args[2:], timeout, tempPrefix, wantStack) print "Exit status: %s (%.3f seconds)" % (runinfo.msg, runinfo.elapsedtime) return runinfo.sta == timedRun.CRASHED or runinfo.sta == timedRun.ABNORMAL
def interesting(cliArgs, tempPrefix): (timeout, args) = parseOptions(cliArgs) runinfo = timedRun.timed_run(args, timeout, tempPrefix) timeString = " (%.3f seconds)" % runinfo.elapsedtime if runinfo.sta == timedRun.CRASHED: print 'Exit status: ' + runinfo.msg + timeString return True else: print "[Uninteresting] It didn't crash." + timeString return False
def interesting(cliArgs, tempPrefix): (timeout, args) = parseOptions(cliArgs) runinfo = timedRun.timed_run(args, timeout, tempPrefix) timeString = " (%.3f seconds)" % runinfo.elapsedtime if runinfo.sta == timedRun.CRASHED: print "Exit status: " + runinfo.msg + timeString return True else: print "[Uninteresting] It didn't crash." + timeString return False
def interesting(cliArgs, tempPrefix): (timeout, aArgs, bArgs, args) = parseOptions(cliArgs) aRuninfo = timedRun.timed_run(args[:1] + aArgs + args[1:], timeout, tempPrefix + "-a") bRuninfo = timedRun.timed_run(args[:1] + bArgs + args[1:], timeout, tempPrefix + "-b") timeString = " (1st Run: %.3f seconds) (2nd Run: %.3f seconds)" % (aRuninfo.elapsedtime, bRuninfo.elapsedtime) if aRuninfo.sta != timedRun.TIMED_OUT and bRuninfo.sta != timedRun.TIMED_OUT: if aRuninfo.rc != bRuninfo.rc: print ("[Interesting] Different return code. (%d, %d) " % (aRuninfo.rc, bRuninfo.rc)) + timeString return True if not filecmp.cmp(aRuninfo.out, bRuninfo.out): print "[Interesting] Different output. " + timeString return True if not filecmp.cmp(aRuninfo.err, bRuninfo.err): print "[Interesting] Different error output. " + timeString return True else: print "[Uninteresting] At least one test timed out." + timeString return False print "[Uninteresting] Identical behaviour." + timeString return False
def interesting(cliArgs, tempPrefix): (timeout, regexEnabled, args) = parseOptions(cliArgs) searchFor = args[0] runinfo = timedRun.timed_run(args[1:], timeout, tempPrefix) result = (fileIngredients.fileContains(tempPrefix + "-out.txt", searchFor, regexEnabled)[0] or fileIngredients.fileContains(tempPrefix + "-err.txt", searchFor, regexEnabled)[0]) print 'Exit status: ' + runinfo.msg + " (%.3f seconds)" % runinfo.elapsedtime return result
def interesting(cliArgs, tempPrefix): (timeout, regexEnabled, args) = parseOptions(cliArgs) searchFor = args[0] runinfo = timedRun.timed_run(args[1:], timeout, tempPrefix) result = ( fileIngredients.fileContains(tempPrefix + "-out.txt", searchFor, regexEnabled)[0] or fileIngredients.fileContains(tempPrefix + "-err.txt", searchFor, regexEnabled)[0] ) print 'Exit status: ' + runinfo.msg + " (%.3f seconds)" % runinfo.elapsedtime return result
def interesting(args, tempPrefix): timeout = int(args[0]) desiredCrashSignature = args[1] runinfo = timedRun.timed_run(args[2:], timeout, tempPrefix) timeString = " (%.3f seconds)" % runinfo.elapsedtime crashLogName = tempPrefix + "-crash" if runinfo.sta == timedRun.CRASHED: if os.path.exists(crashLogName): if filecontains(file(crashLogName), desiredCrashSignature): print "[CrashesAt] It crashed in " + desiredCrashSignature + " :)" + timeString return True else: print "[CrashesAt] It crashed somewhere else!" + timeString return False else: print "[CrashesAt] It appeared to crash, but no crash log was found?" + timeString return False else: print "[CrashesAt] It didn't crash." + timeString return False
def __init__(self, options, runthis, logPrefix, inCompareJIT): pathToBinary = runthis[0] # This relies on the shell being a local one from compileShell.py: pc = ProgramConfiguration.fromBinary(pathToBinary.split('.')[0]) # Ignore trailing ".exe" in Win pc.addProgramArguments(runthis[1:-1]) if options.valgrind: runthis = ( inspectShell.constructVgCmdList(errorCode=VALGRIND_ERROR_EXIT_CODE) + valgrindSuppressions(options.knownPath) + runthis) preexec_fn = ulimitSet if os.name == 'posix' else None runinfo = timedRun.timed_run(runthis, options.timeout, logPrefix, preexec_fn=preexec_fn) lev = JS_FINE issues = [] auxCrashData = [] # FuzzManager expects a list of strings rather than an iterable, so bite the # bullet and 'readlines' everything into memory. with open(logPrefix + "-out.txt") as f: out = f.readlines() with open(logPrefix + "-err.txt") as f: err = f.readlines() if options.valgrind and runinfo.rc == VALGRIND_ERROR_EXIT_CODE: issues.append("valgrind reported an error") lev = max(lev, JS_VG_AMISS) valgrindErrorPrefix = "==" + str(runinfo.pid) + "==" for line in err: if valgrindErrorPrefix and line.startswith(valgrindErrorPrefix): issues.append(line.rstrip()) elif runinfo.sta == timedRun.CRASHED: if sps.grabCrashLog(runthis[0], runinfo.pid, logPrefix, True): with open(logPrefix + "-crash.txt") as f: auxCrashData = [line.strip() for line in f.readlines()] elif detect_malloc_errors.amiss(logPrefix): issues.append("malloc error") lev = max(lev, JS_NEW_ASSERT_OR_CRASH) elif runinfo.rc == 0 and not inCompareJIT: # We might have(??) run jsfunfuzz directly, so check for special kinds of bugs for line in out: if line.startswith("Found a bug: ") and not ("NestTest" in line and oomed(err)): lev = JS_DECIDED_TO_EXIT issues.append(line.rstrip()) if options.shellIsDeterministic and not understoodJsfunfuzzExit(out, err) and not oomed(err): issues.append("jsfunfuzz didn't finish") lev = JS_DID_NOT_FINISH # Copy non-crash issues to where FuzzManager's "AssertionHelper.py" can see it. if lev != JS_FINE: for issue in issues: err.append("[Non-crash bug] " + issue) # Finally, make a CrashInfo object and parse stack traces for asan/crash/assertion bugs crashInfo = CrashInfo.CrashInfo.fromRawCrashData(out, err, pc, auxCrashData=auxCrashData) createCollector.printCrashInfo(crashInfo) if not isinstance(crashInfo, CrashInfo.NoCrashInfo): lev = max(lev, JS_NEW_ASSERT_OR_CRASH) match = options.collector.search(crashInfo) if match[0] is not None: createCollector.printMatchingSignature(match) lev = JS_FINE print logPrefix + " | " + summaryString(issues, lev, runinfo.elapsedtime) if lev != JS_FINE: fileManipulation.writeLinesToFile( ['Number: ' + logPrefix + '\n', 'Command: ' + sps.shellify(runthis) + '\n'] + ['Status: ' + i + "\n" for i in issues], logPrefix + '-summary.txt') self.lev = lev self.out = out self.err = err self.issues = issues self.crashInfo = crashInfo self.match = match self.runinfo = runinfo self.rc = runinfo.rc
def __init__(self, options, runthis, logPrefix, inCompareJIT): pathToBinary = runthis[0] # This relies on the shell being a local one from compileShell.py: pc = ProgramConfiguration.fromBinary( pathToBinary.split('.')[0]) # Ignore trailing ".exe" in Win pc.addProgramArguments(runthis[1:-1]) if options.valgrind: runthis = (inspectShell.constructVgCmdList( errorCode=VALGRIND_ERROR_EXIT_CODE) + valgrindSuppressions(options.knownPath) + runthis) preexec_fn = ulimitSet if os.name == 'posix' else None runinfo = timedRun.timed_run(runthis, options.timeout, logPrefix, preexec_fn=preexec_fn) lev = JS_FINE issues = [] auxCrashData = [] # FuzzManager expects a list of strings rather than an iterable, so bite the # bullet and 'readlines' everything into memory. with open(logPrefix + "-out.txt") as f: out = f.readlines() with open(logPrefix + "-err.txt") as f: err = f.readlines() if options.valgrind and runinfo.rc == VALGRIND_ERROR_EXIT_CODE: issues.append("valgrind reported an error") lev = max(lev, JS_VG_AMISS) valgrindErrorPrefix = "==" + str(runinfo.pid) + "==" for line in err: if valgrindErrorPrefix and line.startswith( valgrindErrorPrefix): issues.append(line.rstrip()) elif runinfo.sta == timedRun.CRASHED: if sps.grabCrashLog(runthis[0], runinfo.pid, logPrefix, True): with open(logPrefix + "-crash.txt") as f: auxCrashData = [line.strip() for line in f.readlines()] elif detect_malloc_errors.amiss(logPrefix): issues.append("malloc error") lev = max(lev, JS_NEW_ASSERT_OR_CRASH) elif runinfo.rc == 0 and not inCompareJIT: # We might have(??) run jsfunfuzz directly, so check for special kinds of bugs for line in out: if line.startswith("Found a bug: ") and not ("NestTest" in line and oomed(err)): lev = JS_DECIDED_TO_EXIT issues.append(line.rstrip()) if options.shellIsDeterministic and not understoodJsfunfuzzExit( out, err) and not oomed(err): issues.append("jsfunfuzz didn't finish") lev = JS_DID_NOT_FINISH # Copy non-crash issues to where FuzzManager's "AssertionHelper.py" can see it. if lev != JS_FINE: for issue in issues: err.append("[Non-crash bug] " + issue) # Finally, make a CrashInfo object and parse stack traces for asan/crash/assertion bugs crashInfo = CrashInfo.CrashInfo.fromRawCrashData( out, err, pc, auxCrashData=auxCrashData) createCollector.printCrashInfo(crashInfo) if not isinstance(crashInfo, CrashInfo.NoCrashInfo): lev = max(lev, JS_NEW_ASSERT_OR_CRASH) match = options.collector.search(crashInfo) if match[0] is not None: createCollector.printMatchingSignature(match) lev = JS_FINE print logPrefix + " | " + summaryString(issues, lev, runinfo.elapsedtime) if lev != JS_FINE: fileManipulation.writeLinesToFile([ 'Number: ' + logPrefix + '\n', 'Command: ' + sps.shellify(options.jsengineWithArgs) + '\n' ] + ['Status: ' + i + "\n" for i in issues], logPrefix + '-summary.txt') self.lev = lev self.out = out self.err = err self.issues = issues self.crashInfo = crashInfo self.match = match self.runinfo = runinfo self.rc = runinfo.rc
def baseLevel(runthis, timeout, knownPath, logPrefix, valgrind=False): if valgrind: runthis = ( inspectShell.constructVgCmdList(errorCode=VALGRIND_ERROR_EXIT_CODE) + valgrindSuppressions(knownPath) + runthis ) preexec_fn = ulimitSet if os.name == "posix" else None runinfo = timedRun.timed_run(runthis, timeout, logPrefix, preexec_fn=preexec_fn) sta = runinfo.sta if sta == timedRun.CRASHED: sps.grabCrashLog(runthis[0], runinfo.pid, logPrefix, True) lev = JS_FINE issues = [] sawAssertion = False if detect_malloc_errors.amiss(logPrefix): issues.append("malloc error") lev = max(lev, JS_MALLOC_ERROR) if valgrind and runinfo.rc == VALGRIND_ERROR_EXIT_CODE: issues.append("valgrind reported an error") lev = max(lev, JS_VG_AMISS) valgrindErrorPrefix = "==" + str(runinfo.pid) + "==" else: valgrindErrorPrefix = None def printNote(note): print "%%% " + note crashWatcher = detect_crashes.CrashWatcher(knownPath, False, printNote) with open(logPrefix + "-err.txt", "rb") as err: for line in err: assertionSeverity, assertionIsNew = detect_assertions.scanLine(knownPath, line) crashWatcher.processOutputLine(line.rstrip()) if assertionIsNew: issues.append(line.rstrip()) lev = max(lev, JS_NEW_ASSERT_OR_CRASH) if assertionSeverity == detect_assertions.FATAL_ASSERT: sawAssertion = True lev = max(lev, JS_KNOWN_CRASH) if valgrindErrorPrefix and line.startswith(valgrindErrorPrefix): issues.append(line.rstrip()) if sta == timedRun.CRASHED and not sawAssertion: crashWatcher.readCrashLog(logPrefix + "-crash.txt") if sawAssertion: # Ignore the crash log, since we've already seen a new assertion failure. pass elif crashWatcher.crashProcessor: crashFrom = " (from " + crashWatcher.crashProcessor + ")" if crashWatcher.crashIsKnown: issues.append("known crash" + crashFrom) lev = max(lev, JS_KNOWN_CRASH) else: issues.append("unknown crash" + crashFrom) lev = max(lev, JS_NEW_ASSERT_OR_CRASH) elif sta == timedRun.TIMED_OUT: issues.append("timed out") lev = max(lev, JS_TIMED_OUT) elif sta == timedRun.ABNORMAL and not (valgrind and runinfo.rc == VALGRIND_ERROR_EXIT_CODE): issues.append("abnormal exit") lev = max(lev, JS_ABNORMAL_EXIT) return (lev, issues, runinfo)
def baseLevel(runthis, timeout, knownPath, logPrefix, valgrind=False): if valgrind: runthis = (inspectShell.constructVgCmdList( errorCode=VALGRIND_ERROR_EXIT_CODE) + valgrindSuppressions(knownPath) + runthis) preexec_fn = ulimitSet if os.name == 'posix' else None runinfo = timedRun.timed_run(runthis, timeout, logPrefix, preexec_fn=preexec_fn) sta = runinfo.sta if sta == timedRun.CRASHED: sps.grabCrashLog(runthis[0], runinfo.pid, logPrefix, True) lev = JS_FINE issues = [] sawAssertion = False if detect_malloc_errors.amiss(logPrefix): issues.append("malloc error") lev = max(lev, JS_MALLOC_ERROR) if valgrind and runinfo.rc == VALGRIND_ERROR_EXIT_CODE: issues.append("valgrind reported an error") lev = max(lev, JS_VG_AMISS) valgrindErrorPrefix = "==" + str(runinfo.pid) + "==" else: valgrindErrorPrefix = None def printNote(note): print "%%% " + note crashWatcher = detect_crashes.CrashWatcher(knownPath, False, printNote) with open(logPrefix + "-err.txt", "rb") as err: for line in err: assertionSeverity, assertionIsNew = detect_assertions.scanLine( knownPath, line) crashWatcher.processOutputLine(line.rstrip()) if assertionIsNew: issues.append(line.rstrip()) lev = max(lev, JS_NEW_ASSERT_OR_CRASH) if assertionSeverity == detect_assertions.FATAL_ASSERT: sawAssertion = True lev = max(lev, JS_KNOWN_CRASH) if valgrindErrorPrefix and line.startswith(valgrindErrorPrefix): issues.append(line.rstrip()) if sta == timedRun.CRASHED and not sawAssertion: crashWatcher.readCrashLog(logPrefix + "-crash.txt") if sawAssertion: # Ignore the crash log, since we've already seen a new assertion failure. pass elif crashWatcher.crashProcessor: crashFrom = " (from " + crashWatcher.crashProcessor + ")" if crashWatcher.crashIsKnown: issues.append("known crash" + crashFrom) lev = max(lev, JS_KNOWN_CRASH) else: issues.append("unknown crash" + crashFrom) lev = max(lev, JS_NEW_ASSERT_OR_CRASH) elif sta == timedRun.TIMED_OUT: issues.append("timed out") lev = max(lev, JS_TIMED_OUT) elif sta == timedRun.ABNORMAL and not (valgrind and runinfo.rc == VALGRIND_ERROR_EXIT_CODE): issues.append("abnormal exit") lev = max(lev, JS_ABNORMAL_EXIT) return (lev, issues, runinfo)