Пример #1
0
    def initRunBrowserOptions(self):
        runBrowserOptions = []
        if self.options.background:
            runBrowserOptions.append("--background")
        if self.dirs.symbolsDir:
            runBrowserOptions.append("--symbols-dir=" + self.dirs.symbolsDir)

        if self.options.valgrind:
            runBrowserOptions.append("--valgrind")

            suppressions = ""
            for suppressionsFile in findIgnoreLists.findIgnoreLists(self.knownPath, "valgrind.txt"):
                suppressions += "--suppressions=" + suppressionsFile + " "

            vgargs = (
                "--error-exitcode=" + str(VALGRIND_ERROR_EXIT_CODE) + " " +
                "--gen-suppressions=all" + " " +
                suppressions +
                "--child-silent-after-fork=yes" + " " +  # First part of the workaround for bug 658840
                # "--leak-check=full" + " " +
                # "--show-possibly-lost=no" + " " +
                "--smc-check=all-non-file" + " " +
                # "--track-origins=yes" + " " +
                # "--num-callers=50" + " " +
                "--quiet"
            )

            runBrowserOptions.append("--vgargs=" + vgargs)  # spaces are okay here

        return runBrowserOptions
def readIgnoreLists(knownPath):
    global ignoreList
    global ready
    ignoreList = []
    for filename in findIgnoreLists.findIgnoreLists(knownPath, "crashes.txt"):
        readIgnoreList(filename)
    ready = True
Пример #3
0
def readIgnoreLists(knownPath):
    global ignoreList
    global ready
    ignoreList = []
    for filename in findIgnoreLists.findIgnoreLists(knownPath, "crashes.txt"):
        readIgnoreList(filename)
    ready = True
Пример #4
0
def readIgnoreLists(knownPath):
    global ready
    for filename in findIgnoreLists.findIgnoreLists(knownPath,
                                                    "assertions.txt"):
        readIgnoreList(filename)
    ready = True
    print "detect_assertions is ready (ignoring %d strings without filenames and %d strings with filenames)" % (
        len(simpleIgnoreList), len(twoPartIgnoreList))
Пример #5
0
def readIgnoreLists(knownPath):
    global ready
    for filename in findIgnoreLists.findIgnoreLists(knownPath, "assertions.txt"):
        readIgnoreList(filename)
    ready = True
    print "detect_assertions is ready (ignoring %d strings without filenames and %d strings with filenames)" % (len(simpleIgnoreList), len(twoPartIgnoreList))
Пример #6
0
def rdfInit(args):
    """
    Returns (levelAndLines, options).

    levelAndLines is a function that runs Firefox in a clean profile and analyzes Firefox's output for bugs.
    """

    parser = OptionParser(usage="%prog [options] browserDir [testcaseURL]")
    parser.add_option("--valgrind",
                      action="store_true", dest="valgrind",
                      default=False,
                      help="use valgrind with a reasonable set of options")
    parser.add_option("-m", "--minlevel",
                      type="int", dest="minimumInterestingLevel",
                      default=DOM_FINE + 1,
                      help="minimum domfuzz level for lithium to consider the testcase interesting")
    parser.add_option("--background",
                      action="store_true", dest="background",
                      default=False,
                      help="Run the browser in the background on Mac (e.g. for local reduction)")
    options, args = parser.parse_args(args)

    if len(args) < 1:
        usage("Missing browserDir argument")
    browserDir = args[0]
    dirs = FigureOutDirs(getFullPath(browserDir))

    # Standalone domInteresting:  Optional. Load this URL or file (rather than the Bugzilla front page)
    # loopdomfuzz:                Optional. Test (and possibly splice/reduce) only this URL, rather than looping (but note the prefs file isn't maintained)
    # Lithium:                    Required. Reduce this file.
    options.argURL = args[1] if len(args) > 1 else ""

    options.browserDir = browserDir  # used by loopdomfuzz

    runBrowserOptions = []
    if options.background:
        runBrowserOptions.append("--background")
    if dirs.symbolsDir:
        runBrowserOptions.append("--symbols-dir=" + dirs.symbolsDir)

    env = os.environ.copy()
    env['MOZ_FUZZING_SAFE'] = '1'
    env['REFTEST_FILES_DIR'] = dirs.reftestFilesDir
    env['ASAN_SYMBOLIZER_PATH'] = os.path.expanduser("~/llvm/build/Release/bin/llvm-symbolizer")
    if dirs.stackwalk:
        env['MINIDUMP_STACKWALK'] = dirs.stackwalk
    runbrowserpy = [sys.executable, "-u", os.path.join(THIS_SCRIPT_DIRECTORY, "runbrowser.py")]

    knownPath = "mozilla-central"

    if options.valgrind:
        runBrowserOptions.append("--valgrind")

        suppressions = ""
        for suppressionsFile in findIgnoreLists.findIgnoreLists(knownPath, "valgrind.txt"):
            suppressions += "--suppressions=" + suppressionsFile + " "

        vgargs = (
            "--error-exitcode=" + str(VALGRIND_ERROR_EXIT_CODE) + " " +
            "--gen-suppressions=all" + " " +
            suppressions +
            "--child-silent-after-fork=yes" + " " +  # First part of the workaround for bug 658840
            # "--leak-check=full" + " " +
            # "--show-possibly-lost=no" + " " +
            "--smc-check=all-non-file" + " " +
            # "--track-origins=yes" + " " +
            # "--num-callers=50" + " " +
            "--quiet"
        )

        runBrowserOptions.append("--vgargs=" + vgargs)  # spaces are okay here

    def levelAndLines(url, logPrefix=None, extraPrefs="", quiet=False, leaveProfile=False):
        """Run Firefox using the profile created above, detecting bugs and stuff."""

        profileDir = mkdtemp(prefix="domfuzz-rdf-profile")
        createDOMFuzzProfile(profileDir)
        writePrefs(profileDir, extraPrefs)

        runBrowserArgs = [dirs.reftestScriptDir, dirs.utilityDir, profileDir]

        assert logPrefix  # :(
        leakLogFile = logPrefix + "-leaks.txt"

        runbrowser = subprocess.Popen(
            runbrowserpy + ["--leak-log-file=" + leakLogFile] + runBrowserOptions + runBrowserArgs + [url],
            stdin=None,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            env=env,
            close_fds=close_fds
        )

        alh = AmissLogHandler(knownPath)
        alh.valgrind = options.valgrind

        # Bug 718208
        if extraPrefs.find("inflation") != -1:
            alh.expectedToRenderInconsistently = True

        statusLinePrefix = "RUNBROWSER INFO | runbrowser.py | runApp: exited with status "
        status = -9000

        # NB: not using 'for line in runbrowser.stdout' because that uses a hidden buffer
        # see http://docs.python.org/library/stdtypes.html#file.next
        while True:
            line = runbrowser.stdout.readline()
            if line != '':
                line = alh.processLine(line)
                if not quiet:
                    print line,
                if line.startswith(statusLinePrefix):
                    status = int(line[len(statusLinePrefix):])
            else:
                break

        lev = DOM_FINE

        if status < 0 and os.name == 'posix':
            # The program was terminated by a signal, which usually indicates a crash.
            signum = -status
            if signum != signal.SIGKILL and signum != signal.SIGTERM and not alh.crashWatcher.crashProcessor:
                # We did not detect a breakpad/ASan crash in the output, but it looks like the process crashed.
                # Look for a core file (to feed to gdb) or log from the Mac crash reporter.
                wantStack = True
                assert alh.theapp
                crashLog = sps.grabCrashLog(alh.theapp, alh.pid, logPrefix, wantStack)
                if crashLog:
                    alh.crashWatcher.readCrashLog(crashLog)
                else:
                    alh.printAndLog("@@@ The browser crashed, but did not leave behind any crash information!")
                    lev = max(lev, DOM_NEW_ASSERT_OR_CRASH)

        if alh.newAssertionFailure:
            lev = max(lev, DOM_NEW_ASSERT_OR_CRASH)
        if alh.mallocFailure:
            lev = max(lev, DOM_MALLOC_ERROR)
        if alh.fuzzerComplained or alh.sawChromeFailure:
            lev = max(lev, DOM_FUZZER_COMPLAINED)
        if alh.sawValgrindComplaint:
            lev = max(lev, DOM_VG_AMISS)

        if alh.timedOut:
            if alh.expectedToHang or options.valgrind:
                alh.printAndLog("%%% An expected hang")
            else:
                alh.printAndLog("@@@ Unexpected hang")
                lev = max(lev, DOM_TIMED_OUT_UNEXPECTEDLY)
        elif alh.crashWatcher.crashProcessor:
            if alh.crashWatcher.crashIsKnown:
                alh.printAndLog("%%% Known crash (from " + alh.crashWatcher.crashProcessor + ")" + alh.crashWatcher.crashSignature)
            else:
                alh.printAndLog("@@@ New crash (from " + alh.crashWatcher.crashProcessor + ")" + alh.crashWatcher.crashSignature)
                lev = max(lev, DOM_NEW_ASSERT_OR_CRASH)
        elif options.valgrind and status == VALGRIND_ERROR_EXIT_CODE:
            # Disabled due to leaks in the glxtest process that Firefox forks on Linux.
            # (Second part of the workaround for bug 658840.)
            # (We detect Valgrind warnings as they happen, instead.)
            #alh.printAndLog("@@@ Valgrind complained via exit code")
            #lev = max(lev, DOM_VG_AMISS)
            pass
        elif status < 0 and os.name == 'posix':
            signame = getSignalName(signum, "unknown signal")
            print "DOMFUZZ INFO | domInteresting.py | Terminated by signal " + str(signum) + " (" + signame + ")"
        elif status == 1:
            alh.printAndLog("%%% Exited with status 1 (OOM or plugin crash?)")
        elif status == -2147483645 and sps.isWin:
            alh.printAndLog("%%% Exited with status -2147483645 (plugin issue, bug 867263?)")
        elif status != 0 and not (sps.isWin and alh.sawFatalAssertion):
            alh.printAndLog("@@@ Abnormal exit (status %d)" % status)
            lev = max(lev, DOM_ABNORMAL_EXIT)

        if 'user_pref("layers.use-deprecated-textures", true);' in extraPrefs:
            # Bug 933569
            # Doing the change *here* only works because this is a small leak that shouldn't affect the reads in alh
            alh.expectedToLeak = True

        if os.path.exists(leakLogFile) and status == 0 and detect_leaks.amiss(knownPath, leakLogFile, verbose=not quiet) and not alh.expectedToLeak:
            alh.printAndLog("@@@ Unexpected leak or leak pattern")
            alh.printAndLog("Leak details: " + os.path.basename(leakLogFile))
            lev = max(lev, DOM_NEW_LEAK)
        else:
            if alh.sawOMGLEAK and not alh.expectedToLeak:
                lev = max(lev, DOM_NEW_LEAK)
            if leakLogFile:
                # Remove the main leak log file, plus any plugin-process leak log files
                for f in glob.glob(leakLogFile + "*"):
                    os.remove(f)

        if (lev > DOM_FINE) and logPrefix:
            with open(logPrefix + "-output.txt", "w") as outlog:
                outlog.writelines(alh.fullLogHead)
            subprocess.call(["gzip", logPrefix + "-output.txt"])
            with open(logPrefix + "-summary.txt", "w") as summaryLogFile:
                summaryLogFile.writelines(alh.summaryLog)

        if (lev == DOM_FINE) and logPrefix:
            removeIfExists(logPrefix + "-core.gz")
            removeIfExists(logPrefix + "-crash.txt")

        if not leaveProfile:
            shutil.rmtree(profileDir)

        print "DOMFUZZ INFO | domInteresting.py | " + str(lev)
        return (lev, alh.FRClines)

    return levelAndLines, options  # return a closure along with the set of options
Пример #7
0
def valgrindSuppressions(knownPath):
    return [
        "--suppressions=" + filename
        for filename in findIgnoreLists.findIgnoreLists(
            knownPath, "valgrind.txt")
    ]
Пример #8
0
def valgrindSuppressions(knownPath):
    return ["--suppressions=" + filename for filename in findIgnoreLists.findIgnoreLists(knownPath, "valgrind.txt")]