def compareLevel(jsEngine, flags, infilename, logPrefix, options, showDetailedDiffs, quickMode): # options dict must be one we can pass to jsInteresting.ShellResult # we also use it directly for knownPath, timeout, and collector # Return: (lev, crashInfo) or (jsInteresting.JS_FINE, None) combos = shellFlags.basicFlagSets(jsEngine) if quickMode: # Only used during initial fuzzing. Allowed to have false negatives. combos = [combos[0]] if len(flags): combos.append(flags) commands = [[jsEngine] + combo + [infilename] for combo in combos] for i in range(0, len(commands)): prefix = logPrefix + "-r" + str(i) command = commands[i] r = jsInteresting.ShellResult(options, command, prefix, True) oom = jsInteresting.oomed(r.err) r.err = ignoreSomeOfStderr(r.err) if (r.rc == 1 or r.rc == 2) and (anyLineContains(r.out, '[[script] scriptArgs*]') or anyLineContains(r.err, '[scriptfile] [scriptarg...]')): print "Got usage error from:" print " " + sps.shellify(command) assert i > 0 jsInteresting.deleteLogs(prefix) elif r.lev > jsInteresting.JS_OVERALL_MISMATCH: # would be more efficient to run lithium on one or the other, but meh print infilename + " | " + jsInteresting.summaryString(r.issues + ["compareJIT found a more serious bug"], r.lev, r.runinfo.elapsedtime) with open(logPrefix + "-summary.txt", 'wb') as f: f.write('\n'.join(r.issues + [sps.shellify(command), "compareJIT found a more serious bug"]) + '\n') print " " + sps.shellify(command) return (r.lev, r.crashInfo) elif r.lev != jsInteresting.JS_FINE or r.rc != 0: print infilename + " | " + jsInteresting.summaryString(r.issues + ["compareJIT is not comparing output, because the shell exited strangely"], r.lev, r.runinfo.elapsedtime) print " " + sps.shellify(command) jsInteresting.deleteLogs(prefix) if i == 0: return (jsInteresting.JS_FINE, None) elif oom: # If the shell or python hit a memory limit, we consider the rest of the computation # "tainted" for the purpose of correctness comparison. message = "compareJIT is not comparing output: OOM" print infilename + " | " + jsInteresting.summaryString(r.issues + [message], r.lev, r.runinfo.elapsedtime) jsInteresting.deleteLogs(prefix) if i == 0: return (jsInteresting.JS_FINE, None) elif i == 0: # Stash output from this run (the first one), so for subsequent runs, we can compare against it. (r0, prefix0) = (r, prefix) else: # Compare the output of this run (r.out) to the output of the first run (r0.out), etc. def fpuOptionDisabledAsmOnOneSide(fpuAsmMsg): fpuOptionDisabledAsm = fpuAsmMsg in r0.err or fpuAsmMsg in r.err fpuOptionDiffers = (("--no-fpu" in commands[0]) != ("--no-fpu" in command)) return fpuOptionDisabledAsm and fpuOptionDiffers def optionDisabledAsmOnOneSide(): asmMsg = "asm.js type error: Disabled by javascript.options.asmjs" optionDisabledAsm = anyLineContains(r0.err, asmMsg) or anyLineContains(r.err, asmMsg) optionDiffers = (("--no-asmjs" in commands[0]) != ("--no-asmjs" in command)) return optionDisabledAsm and optionDiffers mismatchErr = (r.err != r0.err and # --no-fpu (on debug x86_32 only) turns off asm.js compilation, among other things. # This should only affect asm.js diagnostics on stderr. not fpuOptionDisabledAsmOnOneSide("asm.js type error: Disabled by lack of floating point support") and # And also wasm stuff. See bug 1243031. not fpuOptionDisabledAsmOnOneSide("WebAssembly is not supported on the current device") and not optionDisabledAsmOnOneSide()) mismatchOut = (r.out != r0.out) if mismatchErr or mismatchOut: # Generate a short summary for stdout and a long summary for a "*-summary.txt" file. rerunCommand = sps.shellify(['~/funfuzz/js/compareJIT.py', "--flags="+' '.join(flags), "--timeout="+str(options.timeout), options.knownPath, jsEngine, os.path.basename(infilename)]) (summary, issues) = summarizeMismatch(mismatchErr, mismatchOut, prefix0, prefix) summary = " " + sps.shellify(commands[0]) + "\n " + sps.shellify(command) + "\n\n" + summary with open(logPrefix + "-summary.txt", 'wb') as f: f.write(rerunCommand + "\n\n" + summary) print infilename + " | " + jsInteresting.summaryString(issues, jsInteresting.JS_OVERALL_MISMATCH, r.runinfo.elapsedtime) if quickMode: print rerunCommand if showDetailedDiffs: print summary print "" # Create a crashInfo object with empty stdout, and stderr showing diffs pc = ProgramConfiguration.fromBinary(jsEngine) pc.addProgramArguments(flags) crashInfo = CrashInfo.CrashInfo.fromRawCrashData([], summary, pc) return (jsInteresting.JS_OVERALL_MISMATCH, crashInfo) else: # print "compareJIT: match" jsInteresting.deleteLogs(prefix) # All matched :) jsInteresting.deleteLogs(prefix0) return (jsInteresting.JS_FINE, None)
def compareLevel(jsEngine, flags, infilename, logPrefix, options, showDetailedDiffs, quickMode): # options dict must be one we can pass to jsInteresting.ShellResult # we also use it directly for knownPath, timeout, and collector # Return: (lev, crashInfo) or (jsInteresting.JS_FINE, None) combos = shellFlags.basicFlagSets(jsEngine) if quickMode: # Only used during initial fuzzing. Allowed to have false negatives. combos = [combos[0]] if len(flags): combos.append(flags) commands = [[jsEngine] + combo + [infilename] for combo in combos] for i in range(0, len(commands)): prefix = logPrefix + "-r" + str(i) command = commands[i] r = jsInteresting.ShellResult(options, command, prefix, True) oom = jsInteresting.oomed(r.err) r.err = ignoreSomeOfStderr(r.err) if (r.rc == 1 or r.rc == 2) and ( anyLineContains(r.out, '[[script] scriptArgs*]') or anyLineContains(r.err, '[scriptfile] [scriptarg...]')): print "Got usage error from:" print " " + sps.shellify(command) assert i > 0 jsInteresting.deleteLogs(prefix) elif r.lev > jsInteresting.JS_OVERALL_MISMATCH: # would be more efficient to run lithium on one or the other, but meh print infilename + " | " + jsInteresting.summaryString( r.issues + ["compareJIT found a more serious bug"], r.lev, r.runinfo.elapsedtime) with open(logPrefix + "-summary.txt", 'wb') as f: f.write('\n'.join(r.issues + [ sps.shellify(command), "compareJIT found a more serious bug" ]) + '\n') print " " + sps.shellify(command) return (r.lev, r.crashInfo) elif r.lev != jsInteresting.JS_FINE or r.rc != 0: print infilename + " | " + jsInteresting.summaryString( r.issues + [ "compareJIT is not comparing output, because the shell exited strangely" ], r.lev, r.runinfo.elapsedtime) print " " + sps.shellify(command) jsInteresting.deleteLogs(prefix) if i == 0: return (jsInteresting.JS_FINE, None) elif oom: # If the shell or python hit a memory limit, we consider the rest of the computation # "tainted" for the purpose of correctness comparison. message = "compareJIT is not comparing output: OOM" print infilename + " | " + jsInteresting.summaryString( r.issues + [message], r.lev, r.runinfo.elapsedtime) jsInteresting.deleteLogs(prefix) if i == 0: return (jsInteresting.JS_FINE, None) elif i == 0: # Stash output from this run (the first one), so for subsequent runs, we can compare against it. (r0, prefix0) = (r, prefix) else: # Compare the output of this run (r.out) to the output of the first run (r0.out), etc. def fpuOptionDisabledAsmOnOneSide(fpuAsmMsg): fpuOptionDisabledAsm = fpuAsmMsg in r0.err or fpuAsmMsg in r.err fpuOptionDiffers = (("--no-fpu" in commands[0]) != ("--no-fpu" in command)) return fpuOptionDisabledAsm and fpuOptionDiffers def optionDisabledAsmOnOneSide(): asmMsg = "asm.js type error: Disabled by javascript.options.asmjs" optionDisabledAsm = anyLineContains( r0.err, asmMsg) or anyLineContains(r.err, asmMsg) optionDiffers = (("--no-asmjs" in commands[0]) != ("--no-asmjs" in command)) return optionDisabledAsm and optionDiffers mismatchErr = ( r.err != r0.err and # --no-fpu (on debug x86_32 only) turns off asm.js compilation, among other things. # This should only affect asm.js diagnostics on stderr. not fpuOptionDisabledAsmOnOneSide( "asm.js type error: Disabled by lack of floating point support" ) and # And also wasm stuff. See bug 1243031. not fpuOptionDisabledAsmOnOneSide( "WebAssembly is not supported on the current device") and not optionDisabledAsmOnOneSide()) mismatchOut = (r.out != r0.out) if mismatchErr or mismatchOut: # Generate a short summary for stdout and a long summary for a "*-summary.txt" file. rerunCommand = sps.shellify([ '~/funfuzz/js/compareJIT.py', "--flags=" + ' '.join(flags), "--timeout=" + str(options.timeout), options.knownPath, jsEngine, os.path.basename(infilename) ]) (summary, issues) = summarizeMismatch(mismatchErr, mismatchOut, prefix0, prefix) summary = " " + sps.shellify( commands[0]) + "\n " + sps.shellify( command) + "\n\n" + summary with open(logPrefix + "-summary.txt", 'wb') as f: f.write(rerunCommand + "\n\n" + summary) print infilename + " | " + jsInteresting.summaryString( issues, jsInteresting.JS_OVERALL_MISMATCH, r.runinfo.elapsedtime) if quickMode: print rerunCommand if showDetailedDiffs: print summary print "" # Create a crashInfo object with empty stdout, and stderr showing diffs pc = ProgramConfiguration.fromBinary(jsEngine) pc.addProgramArguments(flags) crashInfo = CrashInfo.CrashInfo.fromRawCrashData([], summary, pc) return (jsInteresting.JS_OVERALL_MISMATCH, crashInfo) else: # print "compareJIT: match" jsInteresting.deleteLogs(prefix) # All matched :) jsInteresting.deleteLogs(prefix0) return (jsInteresting.JS_FINE, None)
def compareLevel(jsEngine, flags, infilename, logPrefix, knownPath, timeout, showDetailedDiffs, quickMode): combos = shellFlags.basicFlagSets(jsEngine) if quickMode: # Only used during initial fuzzing. Allowed to have false negatives. combos = [combos[0]] if len(flags): combos.append(flags) commands = [[jsEngine] + combo + [infilename] for combo in combos] for i in range(0, len(commands)): prefix = logPrefix + "-r" + str(i) command = commands[i] (lev, issues, r) = jsInteresting.baseLevel(command, timeout, knownPath, prefix) with open(prefix + "-out.txt") as f: r.out = f.read(lengthLimit) with open(prefix + "-err.txt") as f: r.err = f.read(lengthLimit) oom = jsInteresting.hitMemoryLimit(r.err) if (not oom) and (len(r.err) + 5 > lengthLimit): # The output was too long for Python to read it in all at once. Assume the worst. oom = "stderr too long" r.err = ignoreSomeOfStderr(r.err) if (r.rc == 1 or r.rc == 2) and (r.out.find('[[script] scriptArgs*]') != -1 or r.err.find('[scriptfile] [scriptarg...]') != -1): print "Got usage error from:" print " " + sps.shellify(command) assert i > 0 jsInteresting.deleteLogs(prefix) elif lev > jsInteresting.JS_OVERALL_MISMATCH: # would be more efficient to run lithium on one or the other, but meh print infilename + " | " + jsInteresting.summaryString(issues + ["compareJIT found a more serious bug"], lev, r.elapsedtime) with open(logPrefix + "-summary.txt", 'wb') as f: f.write('\n'.join(issues + [sps.shellify(command), "compareJIT found a more serious bug"]) + '\n') print " " + sps.shellify(command) return lev elif lev != jsInteresting.JS_FINE: print infilename + " | " + jsInteresting.summaryString(issues + ["compareJIT is not comparing output, because the shell exited strangely"], lev, r.elapsedtime) print " " + sps.shellify(command) jsInteresting.deleteLogs(prefix) if i == 0: return jsInteresting.JS_FINE elif oom: # If the shell or python hit a memory limit, we consider the rest of the computation # "tainted" for the purpose of correctness comparison. message = "compareJIT is not comparing output: OOM (" + oom + ")" print infilename + " | " + jsInteresting.summaryString(issues + [message], lev, r.elapsedtime) jsInteresting.deleteLogs(prefix) if i == 0: return jsInteresting.JS_FINE elif i == 0: # Stash output from this run (the first one), so for subsequent runs, we can compare against it. (r0, prefix0) = (r, prefix) else: # Compare the output of this run (r.out) to the output of the first run (r0.out), etc. def fpuOptionDisabledAsmOnOneSide(): # --no-fpu (on debug x86_32 only) turns off asm.js compilation, among other things. # This should only affect asm.js diagnostics on stderr. fpuAsmMsg = "asm.js type error: Disabled by lack of floating point support" fpuOptionDisabledAsm = fpuAsmMsg in r0.err or fpuAsmMsg in r.err fpuOptionDiffers = (("--no-fpu" in commands[0]) != ("--no-fpu" in command)) return (fpuOptionDisabledAsm and fpuOptionDiffers) def optionDisabledAsmOnOneSide(): asmMsg = "asm.js type error: Disabled by javascript.options.asmjs" optionDisabledAsm = asmMsg in r0.err or asmMsg in r.err optionDiffers = (("--no-asmjs" in commands[0]) != ("--no-asmjs" in command)) return (optionDisabledAsm and optionDiffers) mismatchErr = (r.err != r0.err and not fpuOptionDisabledAsmOnOneSide() and not optionDisabledAsmOnOneSide()) mismatchOut = (r.out != r0.out) if mismatchErr or mismatchOut: # Generate a short summary for stdout and a long summary for a "*-summary.txt" file. rerunCommand = sps.shellify(['~/funfuzz/js/compareJIT.py', "--flags="+' '.join(flags), "--timeout="+str(timeout), knownPath, jsEngine, os.path.basename(infilename)]) (summary, issues) = summarizeMismatch(mismatchErr, mismatchOut, prefix0, prefix) summary = " " + sps.shellify(commands[0]) + "\n " + sps.shellify(command) + "\n\n" + summary with open(logPrefix + "-summary.txt", 'wb') as f: f.write(rerunCommand + "\n\n" + summary) print infilename + " | " + jsInteresting.summaryString(issues, jsInteresting.JS_OVERALL_MISMATCH, r.elapsedtime) if quickMode: print rerunCommand if showDetailedDiffs: print summary print "" return jsInteresting.JS_OVERALL_MISMATCH else: #print "compareJIT: match" jsInteresting.deleteLogs(prefix) # All matched :) jsInteresting.deleteLogs(prefix0) return jsInteresting.JS_FINE
def compareLevel(jsEngine, flags, infilename, logPrefix, knownPath, timeout, showDetailedDiffs, quickMode): combos = shellFlags.basicFlagSets(jsEngine) if quickMode: # Only used during initial fuzzing. Allowed to have false negatives. combos = [combos[0]] if len(flags): combos.append(flags) commands = [[jsEngine] + combo + [infilename] for combo in combos] for i in range(0, len(commands)): prefix = logPrefix + "-r" + str(i) command = commands[i] (lev, issues, r) = jsInteresting.baseLevel(command, timeout, knownPath, prefix) with open(prefix + "-out.txt") as f: r.out = f.read(lengthLimit) with open(prefix + "-err.txt") as f: r.err = f.read(lengthLimit) oom = jsInteresting.hitMemoryLimit(r.err) if (not oom) and (len(r.err) + 5 > lengthLimit): # The output was too long for Python to read it in all at once. Assume the worst. oom = "stderr too long" r.err = ignoreSomeOfStderr(r.err) if (r.rc == 1 or r.rc == 2) and (r.out.find('[[script] scriptArgs*]') != -1 or r.err.find('[scriptfile] [scriptarg...]') != -1): print "Got usage error from:" print " " + sps.shellify(command) assert i > 0 jsInteresting.deleteLogs(prefix) elif lev > jsInteresting.JS_OVERALL_MISMATCH: # would be more efficient to run lithium on one or the other, but meh print infilename + " | " + jsInteresting.summaryString( issues + ["compareJIT found a more serious bug"], lev, r.elapsedtime) with open(logPrefix + "-summary.txt", 'wb') as f: f.write('\n'.join(issues + [ sps.shellify(command), "compareJIT found a more serious bug" ]) + '\n') print " " + sps.shellify(command) return lev elif lev != jsInteresting.JS_FINE: print infilename + " | " + jsInteresting.summaryString( issues + [ "compareJIT is not comparing output, because the shell exited strangely" ], lev, r.elapsedtime) print " " + sps.shellify(command) jsInteresting.deleteLogs(prefix) if i == 0: return jsInteresting.JS_FINE elif oom: # If the shell or python hit a memory limit, we consider the rest of the computation # "tainted" for the purpose of correctness comparison. message = "compareJIT is not comparing output: OOM (" + oom + ")" print infilename + " | " + jsInteresting.summaryString( issues + [message], lev, r.elapsedtime) jsInteresting.deleteLogs(prefix) if i == 0: return jsInteresting.JS_FINE elif i == 0: # Stash output from this run (the first one), so for subsequent runs, we can compare against it. (r0, prefix0) = (r, prefix) else: # Compare the output of this run (r.out) to the output of the first run (r0.out), etc. def fpuOptionDisabledAsmOnOneSide(): # --no-fpu (on debug x86_32 only) turns off asm.js compilation, among other things. # This should only affect asm.js diagnostics on stderr. fpuAsmMsg = "asm.js type error: Disabled by lack of floating point support" fpuOptionDisabledAsm = fpuAsmMsg in r0.err or fpuAsmMsg in r.err fpuOptionDiffers = (("--no-fpu" in commands[0]) != ("--no-fpu" in command)) return (fpuOptionDisabledAsm and fpuOptionDiffers) def optionDisabledAsmOnOneSide(): asmMsg = "asm.js type error: Disabled by javascript.options.asmjs" optionDisabledAsm = asmMsg in r0.err or asmMsg in r.err optionDiffers = (("--no-asmjs" in commands[0]) != ("--no-asmjs" in command)) return (optionDisabledAsm and optionDiffers) mismatchErr = (r.err != r0.err and not fpuOptionDisabledAsmOnOneSide() and not optionDisabledAsmOnOneSide()) mismatchOut = (r.out != r0.out) if mismatchErr or mismatchOut: # Generate a short summary for stdout and a long summary for a "*-summary.txt" file. rerunCommand = sps.shellify([ '~/funfuzz/js/compareJIT.py', "--flags=" + ' '.join(flags), "--timeout=" + str(timeout), knownPath, jsEngine, os.path.basename(infilename) ]) (summary, issues) = summarizeMismatch(mismatchErr, mismatchOut, prefix0, prefix) summary = " " + sps.shellify( commands[0]) + "\n " + sps.shellify( command) + "\n\n" + summary with open(logPrefix + "-summary.txt", 'wb') as f: f.write(rerunCommand + "\n\n" + summary) print infilename + " | " + jsInteresting.summaryString( issues, jsInteresting.JS_OVERALL_MISMATCH, r.elapsedtime) if quickMode: print rerunCommand if showDetailedDiffs: print summary print "" return jsInteresting.JS_OVERALL_MISMATCH else: #print "compareJIT: match" jsInteresting.deleteLogs(prefix) # All matched :) jsInteresting.deleteLogs(prefix0) return jsInteresting.JS_FINE