示例#1
0
文件: hgCmds.py 项目: ufwt/funfuzz
def getRepoHashAndId(repoDir, repoRev='parents() and default'):
    '''
    This function returns the repository hash and id, and whether it is on default.
    It also asks what the user would like to do, should the repository not be on default.
    '''
    # This returns null if the repository is not on default.
    hgLogTmplList = [
        'hg', '-R', repoDir, 'log', '-r', repoRev, '--template',
        '{node|short} {rev}'
    ]
    hgIdFull = sps.captureStdout(hgLogTmplList)[0]
    onDefault = bool(hgIdFull)
    if not onDefault:
        updateDefault = raw_input('Not on default tip! ' + \
            'Would you like to (a)bort, update to (d)efault, or (u)se this rev: ')
        if updateDefault == 'a':
            print 'Aborting...'
            sys.exit(0)
        elif updateDefault == 'd':
            subprocess.check_call(['hg', '-R', repoDir, 'update', 'default'])
            onDefault = True
        elif updateDefault == 'u':
            hgLogTmplList = [
                'hg', '-R', repoDir, 'log', '-r', 'parents()', '--template',
                '{node|short} {rev}'
            ]
        else:
            raise Exception('Invalid choice.')
        hgIdFull = sps.captureStdout(hgLogTmplList)[0]
    assert hgIdFull != ''
    (hgIdChangesetHash, hgIdLocalNum) = hgIdFull.split(' ')
    sps.vdump(
        'Finished getting the hash and local id number of the repository.')
    return hgIdChangesetHash, hgIdLocalNum, onDefault
示例#2
0
文件: hgCmds.py 项目: nth10sd/funfuzz
def getRepoHashAndId(repoDir, repoRev="parents() and default"):
    """Return the repository hash and id, and whether it is on default.

    It will also ask what the user would like to do, should the repository not be on default.
    """
    # This returns null if the repository is not on default.
    hgLogTmplList = ["hg", "-R", repoDir, "log", "-r", repoRev, "--template", "{node|short} {rev}"]
    hgIdFull = sps.captureStdout(hgLogTmplList)[0]
    onDefault = bool(hgIdFull)
    if not onDefault:
        updateDefault = raw_input(
            "Not on default tip! " + "Would you like to (a)bort, update to (d)efault, or (u)se this rev: "
        )
        if updateDefault == "a":
            print "Aborting..."
            sys.exit(0)
        elif updateDefault == "d":
            subprocess.check_call(["hg", "-R", repoDir, "update", "default"])
            onDefault = True
        elif updateDefault == "u":
            hgLogTmplList = ["hg", "-R", repoDir, "log", "-r", "parents()", "--template", "{node|short} {rev}"]
        else:
            raise Exception("Invalid choice.")
        hgIdFull = sps.captureStdout(hgLogTmplList)[0]
    assert hgIdFull != ""
    (hgIdChangesetHash, hgIdLocalNum) = hgIdFull.split(" ")
    sps.vdump("Finished getting the hash and local id number of the repository.")
    return hgIdChangesetHash, hgIdLocalNum, onDefault
示例#3
0
def makeShell(shellCacheDir,
              sourceDir,
              archNum,
              compileType,
              valgrindSupport,
              currRev,
              verbose=False):
    tempDir = tempfile.mkdtemp(prefix="abc-" + currRev + "-")
    compileJsSrcPath = normExpUserPath(
        os.path.join(tempDir, 'compilePath', 'js', 'src'))

    vdump("Compiling in " + tempDir)

    # Copy the js tree.
    jsSrcDir = normExpUserPath(os.path.join(sourceDir, 'js', 'src'))
    if sys.version_info >= (2, 6):
        shutil.copytree(
            jsSrcDir,
            compileJsSrcPath,
            ignore=shutil.ignore_patterns(
                # ignore_patterns does not work in Python 2.5.
                'jit-test',
                'tests',
                'trace-test',
                'xpconnect'))
    else:
        shutil.copytree(jsSrcDir, compileJsSrcPath)
    jsPubSrcDir = normExpUserPath(os.path.join(sourceDir, 'js', 'public'))
    if os.path.isdir(jsPubSrcDir):
        shutil.copytree(jsPubSrcDir,
                        os.path.join(compileJsSrcPath, '..', 'public'))
    mfbtSrcDir = normExpUserPath(os.path.join(sourceDir, 'mfbt'))
    if os.path.isdir(mfbtSrcDir):
        shutil.copytree(mfbtSrcDir,
                        os.path.join(compileJsSrcPath, '..', '..', 'mfbt'))

    # Run autoconf.
    autoconfRun(compileJsSrcPath)

    # Create objdir within the compileJsSrcPath.
    objdir = os.path.join(compileJsSrcPath, compileType + '-objdir')
    os.mkdir(objdir)

    # Run configure.
    threadsafe = False  # Let's disable support for threadsafety in the js shell
    cfgPath = normExpUserPath(os.path.join(compileJsSrcPath, 'configure'))
    cfgJsBin(archNum, compileType, threadsafe, cfgPath, objdir)

    # Compile and copy the first binary.
    # Only pymake was tested on Windows.
    usePymake = True if platform.system() == 'Windows' else False
    try:
        shell = compileCopy(archNum, compileType, currRev, usePymake,
                            sourceDir, shellCacheDir, objdir, valgrindSupport,
                            verbose)
    finally:
        assert os.path.isdir(tempDir) is True
        rmDirInclSubDirs(tempDir)
        assert os.path.isdir(tempDir) is False
    return shell
示例#4
0
def getRepoHashAndId(repoDir, repoRev='parents() and default'):
    '''
    This function returns the repository hash and id, and whether it is on default.
    It also asks what the user would like to do, should the repository not be on default.
    '''
    # This returns null if the repository is not on default.
    hgLogTmplList = ['hg', '-R', repoDir, 'log', '-r', repoRev,
                     '--template', '{node|short} {rev}']
    hgIdFull = sps.captureStdout(hgLogTmplList)[0]
    onDefault = bool(hgIdFull)
    if not onDefault:
        updateDefault = raw_input('Not on default tip! ' + \
            'Would you like to (a)bort, update to (d)efault, or (u)se this rev: ')
        if updateDefault == 'a':
            print 'Aborting...'
            sys.exit(0)
        elif updateDefault == 'd':
            subprocess.check_call(['hg', '-R', repoDir, 'update', 'default'])
            onDefault = True
        elif updateDefault == 'u':
            hgLogTmplList = ['hg', '-R', repoDir, 'log', '-r', 'parents()', '--template',
                             '{node|short} {rev}']
        else:
            raise Exception('Invalid choice.')
        hgIdFull = sps.captureStdout(hgLogTmplList)[0]
    assert hgIdFull != ''
    (hgIdChangesetHash, hgIdLocalNum) = hgIdFull.split(' ')
    sps.vdump('Finished getting the hash and local id number of the repository.')
    return hgIdChangesetHash, hgIdLocalNum, onDefault
示例#5
0
def parseOpts(args):
    parser = OptionParser()
    parser.disable_interspersed_args()
    parser.add_option(
        "--comparejit",
        action="store_true",
        dest="useCompareJIT",
        default=False,
        help="After running the fuzzer, run the FCM lines against the engine in two configurations and compare the output.",
    )
    parser.add_option(
        "--random-flags",
        action="store_true",
        dest="randomFlags",
        default=False,
        help="Pass a random set of flags (e.g. --ion-eager) to the js engine",
    )
    parser.add_option(
        "--repo",
        action="store",
        dest="repo",
        default=os.path.expanduser("~/trees/mozilla-central/"),
        help="The hg repository (e.g. ~/trees/mozilla-central/), for bisection",
    )
    parser.add_option(
        "--build", action="store", dest="buildOptionsStr", help="The build options, for bisection", default=None
    )  # if you run loopjsfunfuzz.py directly without a --build, pinpoint will try to guess
    parser.add_option(
        "--valgrind",
        action="store_true",
        dest="valgrind",
        default=False,
        help="use valgrind with a reasonable set of options",
    )
    options, args = parser.parse_args(args)

    if options.valgrind and options.useCompareJIT:
        print "Note: When running comparejit, the --valgrind option will be ignored"

    # kill js shell if it runs this long.
    # jsfunfuzz will quit after half this time if it's not ilooping.
    # higher = more complex mixing, especially with regression tests.
    # lower = less time wasted in timeouts and in compareJIT testcases that are thrown away due to OOMs.
    options.timeout = int(args[0])

    options.knownPath = os.path.expanduser(args[1])
    # FIXME: findIgnoreLists.py should probably check this automatically.
    reposWithKnownLists = ["mozilla-central", "mozilla-esr45", "ionmonkey", "jscore", "v8"]
    if options.knownPath not in reposWithKnownLists:
        sps.vdump(
            "Known bugs for the "
            + options.knownPath
            + " repository does not exist. Using the list for mozilla-central instead."
        )
        options.knownPath = "mozilla-central"
    options.jsEngine = args[2]
    options.engineFlags = args[3:]

    return options
示例#6
0
def bisectLabel(hgPrefix, options, hgLabel, currRev, startRepo, endRepo):
    """Tell hg what we learned about the revision."""
    assert hgLabel in ("good", "bad", "skip")
    outputResult = sps.captureStdout(hgPrefix +
                                     ['bisect', '-U', '--' +
                                      hgLabel, currRev])[0]
    outputLines = outputResult.split("\n")

    if options.buildOptions:
        repoDir = options.buildOptions.repoDir

    if re.compile(
            "Due to skipped revisions, the first (good|bad) revision could be any of:"
    ).match(outputLines[0]):
        print()
        print(sanitizeCsetMsg(outputResult, repoDir))
        print()
        return None, None, None, startRepo, endRepo

    r = re.compile("The first (good|bad) revision is:")
    m = r.match(outputLines[0])
    if m:
        print()
        print()
        print(
            "autoBisect shows this is probably related to the following changeset:"
        )
        print()
        print(sanitizeCsetMsg(outputResult, repoDir))
        print()
        blamedGoodOrBad = m.group(1)
        blamedRev = hgCmds.getCsetHashFromBisectMsg(outputLines[1])
        return blamedGoodOrBad, blamedRev, None, startRepo, endRepo

    if options.testInitialRevs:
        return None, None, None, startRepo, endRepo

    # e.g. "Testing changeset 52121:573c5fa45cc4 (440 changesets remaining, ~8 tests)"
    sps.vdump(outputLines[0])

    currRev = hgCmds.getCsetHashFromBisectMsg(outputLines[0])
    if currRev is None:
        print("Resetting to default revision...")
        subprocess.check_call(hgPrefix + ['update', '-C', 'default'])
        hgCmds.destroyPyc(repoDir)
        raise Exception("hg did not suggest a changeset to test!")

    # Update the startRepo/endRepo values.
    start = startRepo
    end = endRepo
    if hgLabel == 'bad':
        end = currRev
    elif hgLabel == 'good':
        start = currRev
    elif hgLabel == 'skip':
        pass

    return None, None, currRev, start, end
示例#7
0
def httpDirList(directory):
    """Read an Apache-style directory listing and returns a list of its contents, as relative URLs."""
    print "Looking in " + directory + " ..."
    page = readFromURL(directory)
    sps.vdump('Finished reading from: ' + directory)

    parser = MyHTMLParser()
    fileList = parser.getHrefLinks(page, directory)
    return fileList
示例#8
0
def testBinary(shellPath, args, useValgrind):
    '''Tests the given shell with the given args.'''
    testCmd = (constructVgCmdList() if useValgrind else []) + [shellPath] + args
    sps.vdump('The testing command is: ' + sps.shellify(testCmd))
    out, rCode = sps.captureStdout(testCmd, combineStderr=True, ignoreStderr=True,
                                   ignoreExitCode=True, env=envVars.envWithPath(
                                       os.path.dirname(os.path.abspath(shellPath))))
    sps.vdump('The exit code is: ' + str(rCode))
    return out, rCode
示例#9
0
def httpDirList(directory):
    """Read an Apache-style directory listing and returns a list of its contents, as relative URLs."""
    print("Looking in %s ..." % directory)
    page = readFromURL(directory)
    sps.vdump('Finished reading from: ' + directory)

    parser = MyHTMLParser()
    fileList = parser.getHrefLinks(page, directory)
    return fileList
示例#10
0
def testBinary(shell, file, flagsRequired, valgSupport, verbose=False, timeout=None):
    testBinaryCmd = [shell] + flagsRequired + [file]
    if valgSupport:
        valgPrefixCmd = []
        valgPrefixCmd.append('valgrind')
        if platform.system() == 'Darwin':
            valgPrefixCmd.append('--dsymutil=yes')
        valgPrefixCmd.append('--smc-check=all-non-file')
        valgPrefixCmd.append('--leak-check=full')
        testBinaryCmd = valgPrefixCmd + testBinaryCmd
    vdump('The testing command is:' + ' '.join(testBinaryCmd))

    # Capture stdout and stderr into the same string.
    p = subprocess.Popen(testBinaryCmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    (out,err) = ('', '')
    retCode = 0

    if (timeout != None):
        signal.signal(signal.SIGALRM, alarm_handler)
        signal.alarm(timeout)  # 5 minutes
    try:
        out, err = p.communicate()
        signal.alarm(0)
        retCode = p.returncode
    except Alarm:
        p.terminate()

    if verbose:
        print 'The exit code is:', retCode
        if len(out) > 0:
            print 'stdout shows:', out
        if len(err) > 0:
            print 'stderr shows:', err

    # Switch to interactive input mode similar to `cat testcase.js | ./js -j -i`.
    # Doesn't work, stdout shows:
    #can't open : No such file or directory
    #The exit code is: 4
    #The second output is: None
    #if retCode == 0:
    #    # Append the quit() function to make the testcase quit.
    #    # Doesn't work if retCode is something other than 0, that watchExitCode specified.
    #    testcaseFile = open(file, 'a')
    #    testcaseFile.write('\nquit()\n')
    #    testcaseFile.close()
    #
    #    # Test interactive input.
    #    print 'Switching to interactive input mode in case passing as a CLI ' + \
    #            'argument does not reproduce the issue..'
    #    testBinaryCmd3 = subprocess.Popen([shell, methodJit, tracingJit, '-i'],
    #        stdin=(subprocess.Popen(['cat', file])).stdout)
    #    output2 = testBinaryCmd3.communicate()[0]
    #    retCode = testBinaryCmd3.returncode
    #    print 'The exit code is:', retCode
    #    print 'The second output is:', output2
    return out + "\n" + err, retCode
示例#11
0
def testBinary(shellPath, args, useValgrind):
    '''Tests the given shell with the given args.'''
    testCmd = (constructVgCmdList() if useValgrind else []) + [shellPath] + args
    sps.vdump('The testing command is: ' + sps.shellify(testCmd))
    out, rCode = sps.captureStdout(testCmd, combineStderr=True, ignoreStderr=True,
                                   ignoreExitCode=True, env=envVars.envWithPath(
                                       os.path.dirname(os.path.abspath(shellPath))))
    sps.vdump('The exit code is: ' + str(rCode))
    return out, rCode
示例#12
0
def httpDirList(directory):
    '''
    Reads in an input directory and returns the href links in the directory as a list.
    '''
    print "Looking in " + directory + " ..."
    page = readFromURL(directory)
    sps.vdump('Finished reading from: ' + directory)

    parser = MyHTMLParser()
    fileList = parser.getHrefLinks(page)
    return fileList
示例#13
0
def bisectLabel(hgPrefix, options, hgLabel, currRev, startRepo, endRepo):
    '''Tell hg what we learned about the revision.'''
    assert hgLabel in ("good", "bad", "skip")
    outputResult = sps.captureStdout(hgPrefix + ['bisect', '-U', '--' + hgLabel, currRev])[0]
    outputLines = outputResult.split("\n")

    repoDir = options.buildOptions.repoDir if options.buildOptions else options.browserOptions.repoDir

    if re.compile("Due to skipped revisions, the first (good|bad) revision could be any of:").match(outputLines[0]):
        print '\n' + sanitizeCsetMsg(outputResult, repoDir) + '\n'
        return None, None, None, startRepo, endRepo

    r = re.compile("The first (good|bad) revision is:")
    m = r.match(outputLines[0])
    if m:
        print '\n\nautoBisect shows this is probably related to the following changeset:\n'
        print sanitizeCsetMsg(outputResult, repoDir) + '\n'
        blamedGoodOrBad = m.group(1)
        blamedRev = hgCmds.getCsetHashFromBisectMsg(outputLines[1])
        return blamedGoodOrBad, blamedRev, None, startRepo, endRepo

    if options.testInitialRevs:
        return None, None, None, startRepo, endRepo

    # e.g. "Testing changeset 52121:573c5fa45cc4 (440 changesets remaining, ~8 tests)"
    sps.vdump(outputLines[0])

    currRev = hgCmds.getCsetHashFromBisectMsg(outputLines[0])
    if currRev is None:
        print 'Resetting to default revision...'
        subprocess.check_call(hgPrefix + ['update', '-C', 'default'])
        hgCmds.destroyPyc(repoDir)
        raise Exception("hg did not suggest a changeset to test!")

    # Update the startRepo/endRepo values.
    start = startRepo
    end = endRepo
    if hgLabel == 'bad':
        end = currRev
    elif hgLabel == 'good':
        start = currRev
    elif hgLabel == 'skip':
        pass

    return None, None, currRev, start, end
示例#14
0
def parseOpts(args):
    parser = OptionParser()
    parser.disable_interspersed_args()
    parser.add_option("--comparejit",
                      action="store_true", dest="useCompareJIT",
                      default=False,
                      help="After running the fuzzer, run the FCM lines against the engine in two configurations and compare the output.")
    parser.add_option("--random-flags",
                      action="store_true", dest="randomFlags",
                      default=False,
                      help="Pass a random set of flags (e.g. --ion-eager) to the js engine")
    parser.add_option("--repo",
                      action="store", dest="repo",
                      default=os.path.expanduser("~/trees/mozilla-central/"),
                      help="The hg repository (e.g. ~/trees/mozilla-central/), for bisection")
    parser.add_option("--build",
                      action="store", dest="buildOptionsStr",
                      help="The build options, for bisection",
                      default=None)  # if you run loopjsfunfuzz.py directly without a --build, pinpoint will try to guess
    parser.add_option("--valgrind",
                      action="store_true", dest="valgrind",
                      default=False,
                      help="use valgrind with a reasonable set of options")
    options, args = parser.parse_args(args)

    if options.valgrind and options.useCompareJIT:
        print "Note: When running comparejit, the --valgrind option will be ignored"

    # kill js shell if it runs this long.
    # jsfunfuzz will quit after half this time if it's not ilooping.
    # higher = more complex mixing, especially with regression tests.
    # lower = less time wasted in timeouts and in compareJIT testcases that are thrown away due to OOMs.
    options.timeout = int(args[0])

    options.knownPath = os.path.expanduser(args[1])
    # FIXME: findIgnoreLists.py should probably check this automatically.
    reposWithKnownLists = ['mozilla-central', 'ionmonkey', 'jscore', 'v8']
    if options.knownPath not in reposWithKnownLists:
        sps.vdump('Known bugs for the ' + options.knownPath + ' repository does not exist. Using the list for mozilla-central instead.')
        options.knownPath = 'mozilla-central'
    options.jsEngine = args[2]
    options.engineFlags = args[3:]

    return options
示例#15
0
def hgHashAddToFuzzPath(fuzzPath, repoDir):
    '''
    This function finds the mercurial revision and appends it to the directory name.
    It also prompts if the user wants to continue, should the repository not be on tip.
    '''
    hgIdCmdList = ['hg', 'identify', '-i', '-n', '-b', repoDir]
    vdump('About to start running `' + ' '.join(hgIdCmdList) + '` ...')
    # In Windows, this throws up a warning about failing to set color mode to win32.
    if platform.system() == 'Windows':
        hgIdFull = captureStdout(hgIdCmdList,
                                 currWorkingDir=repoDir,
                                 ignoreStderr=True)[0]
    else:
        hgIdFull = captureStdout(hgIdCmdList, currWorkingDir=repoDir)[0]
    hgIdChangesetHash = hgIdFull.split(' ')[0]
    hgIdLocalNum = hgIdFull.split(' ')[1]
    # In Windows, this throws up a warning about failing to set color mode to win32.
    if platform.system() == 'Windows':
        hgIdBranch = captureStdout(['hg', 'id', '-t'],
                                   currWorkingDir=repoDir,
                                   ignoreStderr=True)[0]
    else:
        hgIdBranch = captureStdout(['hg', 'id', '-t'],
                                   currWorkingDir=repoDir)[0]
    onDefaultTip = True
    if 'tip' not in hgIdBranch:
        print 'The repository is at this changeset -', hgIdLocalNum + ':' + hgIdChangesetHash
        notOnDefaultTipApproval = str(
            raw_input(
                'Not on default tip! Are you sure you want to continue? (y/n): '
            ))
        if notOnDefaultTipApproval == ('y' or 'yes'):
            onDefaultTip = False
        else:
            switchToDefaultTipApproval = str(
                raw_input('Do you want to switch to the default tip? (y/n): '))
            if switchToDefaultTipApproval == ('y' or 'yes'):
                subprocess.check_call(['hg', 'up', 'default'], cwd=repoDir)
            else:
                raise Exception('Not on default tip.')
    fuzzPath = '-'.join([fuzzPath, hgIdLocalNum, hgIdChangesetHash])
    vdump('Finished running `' + ' '.join(hgIdCmdList) + '`.')
    return normExpUserPath(fuzzPath), onDefaultTip
示例#16
0
def patchHgRepoUsingMq(patchLoc, cwd=os.getcwdu()):
    # We may have passed in the patch with or without the full directory.
    p = os.path.abspath(normExpUserPath(patchLoc))
    pname = os.path.basename(p)
    assert (p, pname) != ('', '')
    subprocess.check_call(['hg', 'qimport', p], cwd=cwd)
    vdump("Patch qimport'ed.")
    try:
        subprocess.check_call(['hg', 'qpush', pname], cwd=cwd)
        vdump("Patch qpush'ed.")
    except subprocess.CalledProcessError:
        subprocess.check_call(['hg', 'qpop'], cwd=cwd)
        subprocess.check_call(['hg', 'qdelete', pname], cwd=cwd)
        print 'You may have untracked .rej files in the repository.'
        print '`hg st` output of the repository in ' + cwd + ' :'
        subprocess.check_call(['hg', 'st'], cwd=cwd)
        hgPurgeAns = str(raw_input('Do you want to run `hg purge`? (y/n): '))
        assert hgPurgeAns.lower() in ('y', 'n')
        if hgPurgeAns == 'y':
            subprocess.check_call(['hg', 'purge'], cwd=cwd)
        raise Exception(format_exc())
    return pname
示例#17
0
def cfgBin(shell):
    '''This function configures a binary according to required parameters.'''
    cfgCmdList = []
    cfgEnvDt = copy.deepcopy(os.environ)
    origCfgEnvDt = copy.deepcopy(os.environ)
    cfgEnvDt['AR'] = 'ar'
    if sps.isARMv7l:
        # 32-bit shell on ARM boards, e.g. odroid boards.
        # This is tested on Ubuntu 14.04 with necessary armel libraries (force)-installed.
        assert shell.buildOptions.enable32, 'arm7vl boards are only 32-bit, armv8 boards will be 64-bit.'
        if not shell.buildOptions.enableHardFp:
            cfgEnvDt[
                'CC'] = 'gcc-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7'
            cfgEnvDt[
                'CXX'] = 'g++-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7'
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        # From mjrosenb: things might go wrong if these three lines are not present for
        # compiling ARM on a 64-bit host machine. Not needed if compiling on the board itself.
        # cfgCmdList.append('--target=arm-linux-gnueabi')
        # cfgCmdList.append('--with-arch=armv7-a')
        # cfgCmdList.append('--with-thumb')
        if not shell.buildOptions.enableHardFp:
            cfgCmdList.append('--target=arm-linux-gnueabi')
    elif shell.buildOptions.enable32 and os.name == 'posix':
        # 32-bit shell on Mac OS X 10.10 Yosemite and greater
        if sps.isMac:
            assert sps.macVer() >= [
                10, 10
            ]  # We no longer support 10.9 Mavericks and prior.
            # Uses system clang
            cfgEnvDt['CC'] = cfgEnvDt[
                'HOST_CC'] = 'clang' + CLANG_PARAMS + SSE2_FLAGS
            cfgEnvDt['CXX'] = cfgEnvDt[
                'HOST_CXX'] = 'clang++' + CLANG_PARAMS + SSE2_FLAGS
            if shell.buildOptions.buildWithAsan:
                cfgEnvDt['CC'] += CLANG_ASAN_PARAMS
                cfgEnvDt['CXX'] += CLANG_ASAN_PARAMS
            cfgEnvDt['CC'] = cfgEnvDt[
                'CC'] + CLANG_X86_FLAG  # only needed for CC, not HOST_CC
            cfgEnvDt['CXX'] = cfgEnvDt[
                'CXX'] + CLANG_X86_FLAG  # only needed for CXX, not HOST_CXX
            cfgEnvDt['RANLIB'] = 'ranlib'
            cfgEnvDt['AS'] = '$CC'
            cfgEnvDt['LD'] = 'ld'
            cfgEnvDt['STRIP'] = 'strip -x -S'
            cfgEnvDt['CROSS_COMPILE'] = '1'
            if sps.isProgramInstalled('brew'):
                cfgEnvDt[
                    'AUTOCONF'] = '/usr/local/Cellar/autoconf213/2.13/bin/autoconf213'
            cfgCmdList.append('sh')
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append(
                '--target=i386-apple-darwin14.5.0')  # Yosemite 10.10.5
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append('--enable-address-sanitizer')
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                # Newer configure.in changes mean that things blow up if unknown/removed configure
                # options are entered, so specify it only if it's requested.
                if shell.buildOptions.enableArmSimulatorObsolete:
                    cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        # 32-bit shell on 32/64-bit x86 Linux
        elif sps.isLinux and not sps.isARMv7l:
            cfgEnvDt['PKG_CONFIG_LIBDIR'] = '/usr/lib/pkgconfig'
            if shell.buildOptions.buildWithClang:
                cfgEnvDt['CC'] = cfgEnvDt[
                    'HOST_CC'] = 'clang' + CLANG_PARAMS + SSE2_FLAGS + CLANG_X86_FLAG
                cfgEnvDt['CXX'] = cfgEnvDt[
                    'HOST_CXX'] = 'clang++' + CLANG_PARAMS + SSE2_FLAGS + CLANG_X86_FLAG
            else:
                # apt-get `lib32z1 gcc-multilib g++-multilib` first, if on 64-bit Linux.
                cfgEnvDt['CC'] = 'gcc -m32' + SSE2_FLAGS
                cfgEnvDt['CXX'] = 'g++ -m32' + SSE2_FLAGS
            if shell.buildOptions.buildWithAsan:
                cfgEnvDt['CC'] += CLANG_ASAN_PARAMS
                cfgEnvDt['CXX'] += CLANG_ASAN_PARAMS
            cfgCmdList.append('sh')
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append('--target=i686-pc-linux')
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append('--enable-address-sanitizer')
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                # Newer configure.in changes mean that things blow up if unknown/removed configure
                # options are entered, so specify it only if it's requested.
                if shell.buildOptions.enableArmSimulatorObsolete:
                    cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        else:
            cfgCmdList.append('sh')
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
    # 64-bit shell on Mac OS X 10.10 Yosemite and greater
    elif sps.isMac and sps.macVer() >= [10, 10
                                        ] and not shell.buildOptions.enable32:
        cfgEnvDt['CC'] = 'clang' + CLANG_PARAMS
        cfgEnvDt['CXX'] = 'clang++' + CLANG_PARAMS
        if shell.buildOptions.buildWithAsan:
            cfgEnvDt['CC'] += CLANG_ASAN_PARAMS
            cfgEnvDt['CXX'] += CLANG_ASAN_PARAMS
        if sps.isProgramInstalled('brew'):
            cfgEnvDt[
                'AUTOCONF'] = '/usr/local/Cellar/autoconf213/2.13/bin/autoconf213'
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        cfgCmdList.append(
            '--target=x86_64-apple-darwin14.5.0')  # Yosemite 10.10.5
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append('--enable-address-sanitizer')
        if shell.buildOptions.enableSimulatorArm64:
            cfgCmdList.append('--enable-simulator=arm64')

    elif sps.isWin:
        cfgEnvDt['MAKE'] = 'mozmake'  # Workaround for bug 948534
        if shell.buildOptions.buildWithClang:
            cfgEnvDt['CC'] = 'clang-cl.exe' + CLANG_PARAMS
            cfgEnvDt['CXX'] = 'clang-cl.exe' + CLANG_PARAMS
        # Note: Doesn't seem to work yet.
        # if shell.buildOptions.buildWithAsan:
        #     cfgEnvDt['CC'] += CLANG_ASAN_PARAMS
        #     cfgEnvDt['CXX'] += CLANG_ASAN_PARAMS
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.enable32:
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                # Newer configure.in changes mean that things blow up if unknown/removed configure
                # options are entered, so specify it only if it's requested.
                if shell.buildOptions.enableArmSimulatorObsolete:
                    cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        else:
            cfgCmdList.append('--host=x86_64-pc-mingw32')
            cfgCmdList.append('--target=x86_64-pc-mingw32')
            if shell.buildOptions.enableSimulatorArm64:
                cfgCmdList.append('--enable-simulator=arm64')
        # Note: Doesn't seem to work yet.
        # if shell.buildOptions.buildWithAsan:
        #     cfgCmdList.append('--enable-address-sanitizer')
    else:
        # We might still be using GCC on Linux 64-bit, so do not use clang unless Asan is specified
        if shell.buildOptions.buildWithClang:
            cfgEnvDt['CC'] = 'clang' + CLANG_PARAMS
            cfgEnvDt['CXX'] = 'clang++' + CLANG_PARAMS
        if shell.buildOptions.buildWithAsan:
            cfgEnvDt['CC'] += CLANG_ASAN_PARAMS
            cfgEnvDt['CXX'] += CLANG_ASAN_PARAMS
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append('--enable-address-sanitizer')

    if shell.buildOptions.buildWithClang:
        if sps.isWin:
            assert 'clang-cl' in cfgEnvDt['CC']
            assert 'clang-cl' in cfgEnvDt['CXX']
        else:
            assert 'clang' in cfgEnvDt['CC']
            assert 'clang++' in cfgEnvDt['CXX']
        cfgCmdList.append('--disable-jemalloc')  # See bug 1146895

    if shell.buildOptions.enableDbg:
        cfgCmdList.append('--enable-debug')
    elif shell.buildOptions.disableDbg:
        cfgCmdList.append('--disable-debug')

    if shell.buildOptions.enableOpt:
        cfgCmdList.append('--enable-optimize' +
                          ('=-O1' if shell.buildOptions.buildWithVg else ''))
    elif shell.buildOptions.disableOpt:
        cfgCmdList.append('--disable-optimize')
    if shell.buildOptions.enableProfiling:
        cfgCmdList.append('--enable-profiling')

    if shell.buildOptions.enableMoreDeterministic:
        # Fuzzing tweaks for more useful output, implemented in bug 706433
        cfgCmdList.append('--enable-more-deterministic')
    if shell.buildOptions.enableOomBreakpoint:  # Extra debugging help for OOM assertions
        cfgCmdList.append('--enable-oom-breakpoint')
    if shell.buildOptions.enableWithoutIntlApi:  # Speeds up compilation but is non-default
        cfgCmdList.append('--without-intl-api')

    if shell.buildOptions.buildWithVg:
        cfgCmdList.append('--enable-valgrind')
        cfgCmdList.append('--disable-jemalloc')

    # We add the following flags by default.
    if os.name == 'posix':
        cfgCmdList.append('--with-ccache')
    cfgCmdList.append('--enable-gczeal')
    cfgCmdList.append(
        '--enable-debug-symbols')  # gets debug symbols on opt shells
    cfgCmdList.append('--disable-tests')

    if os.name == 'nt':
        # FIXME: Replace this with sps.shellify.
        counter = 0
        for entry in cfgCmdList:
            if os.sep in entry:
                assert sps.isWin  # MozillaBuild on Windows sometimes confuses "/" and "\".
                cfgCmdList[counter] = cfgCmdList[counter].replace(os.sep, '//')
            counter = counter + 1

    # Print whatever we added to the environment
    envVarList = []
    for envVar in set(cfgEnvDt.keys()) - set(origCfgEnvDt.keys()):
        strToBeAppended = envVar + '="' + cfgEnvDt[envVar] + '"' \
            if ' ' in cfgEnvDt[envVar] else envVar + '=' + cfgEnvDt[envVar]
        envVarList.append(strToBeAppended)
    sps.vdump('Command to be run is: ' + sps.shellify(envVarList) + ' ' +
              sps.shellify(cfgCmdList))

    wDir = shell.getJsObjdir()
    assert os.path.isdir(wDir)

    if sps.isWin:
        changedCfgCmdList = []
        for entry in cfgCmdList:
            # For JS, quoted from :glandium: "the way icu subconfigure is called is what changed.
            #   but really, the whole thing likes forward slashes way better"
            # See bug 1038590 comment 9.
            if '\\' in entry:
                entry = entry.replace('\\', '/')
            changedCfgCmdList.append(entry)
        sps.captureStdout(changedCfgCmdList,
                          ignoreStderr=True,
                          currWorkingDir=wDir,
                          env=cfgEnvDt)
    else:
        sps.captureStdout(cfgCmdList,
                          ignoreStderr=True,
                          currWorkingDir=wDir,
                          env=cfgEnvDt)

    shell.setEnvAdded(envVarList)
    shell.setEnvFull(cfgEnvDt)
    shell.setCfgCmdExclEnv(cfgCmdList)
示例#18
0
def cfgBin(shell, binToBeCompiled):
    '''This function configures a binary according to required parameters.'''
    cfgCmdList = []
    cfgEnvDt = copy.deepcopy(os.environ)
    origCfgEnvDt = copy.deepcopy(os.environ)
    cfgEnvDt['AR'] = 'ar'
    # Check for determinism to prevent LLVM compilation from happening on releng machines,
    # since releng machines only test non-deterministic builds.
    if shell.buildOptions.buildWithAsan and shell.buildOptions.enableMoreDeterministic:
        llvmPath = envVars.findLlvmBinPath()
        assert llvmPath is not None
        CLANG_PATH = sps.normExpUserPath(os.path.join(llvmPath, 'clang'))
        CLANGPP_PATH = sps.normExpUserPath(os.path.join(llvmPath, 'clang++'))

    if sps.isARMv7l:
        # 32-bit shell on ARM boards, e.g. odroid boards.
        # This is tested on Ubuntu 14.04 with necessary armel libraries (force)-installed.
        assert shell.buildOptions.enable32, 'arm7vl boards are only 32-bit, armv8 boards will be 64-bit.'
        if not shell.buildOptions.enableHardFp:
            cfgEnvDt['CC'] = 'gcc-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7'
            cfgEnvDt['CXX'] = 'g++-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7'
        cfgCmdList.append('sh')
        if binToBeCompiled == 'nspr':
            cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
        else:
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            # From mjrosenb: things might go wrong if these three lines are not present for
            # compiling ARM on a 64-bit host machine. Not needed if compiling on the board itself.
            # cfgCmdList.append('--target=arm-linux-gnueabi')
            # cfgCmdList.append('--with-arch=armv7-a')
            # cfgCmdList.append('--with-thumb')
        if not shell.buildOptions.enableHardFp:
            cfgCmdList.append('--target=arm-linux-gnueabi')
    elif shell.buildOptions.enable32 and os.name == 'posix':
        # 32-bit shell on Mac OS X 10.7 Lion and greater
        if sps.isMac:
            assert sps.macVer() >= [10, 7]  # We no longer support Snow Leopard 10.6 and prior.
            if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
                cfgEnvDt['CC'] = cfgEnvDt['HOST_CC'] = CLANG_PATH + CLANG_PARAMS + \
                    CLANG_ASAN_PARAMS + SSE2_FLAGS
                cfgEnvDt['CXX'] = cfgEnvDt['HOST_CXX'] = CLANGPP_PATH + CLANG_PARAMS + \
                    CLANG_ASAN_PARAMS + SSE2_FLAGS
            else:  # Uses system clang
                cfgEnvDt['CC'] = cfgEnvDt['HOST_CC'] = 'clang' + CLANG_PARAMS + SSE2_FLAGS
                cfgEnvDt['CXX'] = cfgEnvDt['HOST_CXX'] = 'clang++' + CLANG_PARAMS + SSE2_FLAGS
            cfgEnvDt['CC'] = cfgEnvDt['CC'] + CLANG_X86_FLAG  # only needed for CC, not HOST_CC
            cfgEnvDt['CXX'] = cfgEnvDt['CXX'] + CLANG_X86_FLAG  # only needed for CXX, not HOST_CXX
            cfgEnvDt['RANLIB'] = 'ranlib'
            cfgEnvDt['AS'] = '$CC'
            cfgEnvDt['LD'] = 'ld'
            cfgEnvDt['STRIP'] = 'strip -x -S'
            cfgEnvDt['CROSS_COMPILE'] = '1'
            if sps.isProgramInstalled('brew'):
                cfgEnvDt['AUTOCONF'] = '/usr/local/Cellar/autoconf213/2.13/bin/autoconf213'
            cfgCmdList.append('sh')
            if binToBeCompiled == 'nspr':
                cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            else:
                cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append('--target=i386-apple-darwin9.2.0')  # Leopard 10.5.2
            cfgCmdList.append('--enable-macos-target=10.5')
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append('--enable-address-sanitizer')
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        # 32-bit shell on 32/64-bit x86 Linux
        elif sps.isLinux and not sps.isARMv7l:
            cfgEnvDt['PKG_CONFIG_LIBDIR'] = '/usr/lib/pkgconfig'
            if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
                cfgEnvDt['CC'] = cfgEnvDt['HOST_CC'] = CLANG_PATH + CLANG_PARAMS + \
                    CLANG_ASAN_PARAMS + SSE2_FLAGS + CLANG_X86_FLAG
                cfgEnvDt['CXX'] = cfgEnvDt['HOST_CXX'] = CLANGPP_PATH + CLANG_PARAMS + \
                    CLANG_ASAN_PARAMS + SSE2_FLAGS + CLANG_X86_FLAG
            else:  # Uses system clang
                # We might still be using GCC on Linux 32-bit, use clang only if we specify ASan
                # apt-get `lib32z1 gcc-multilib g++-multilib` first, if on 64-bit Linux.
                cfgEnvDt['CC'] = 'gcc -m32' + SSE2_FLAGS
                cfgEnvDt['CXX'] = 'g++ -m32' + SSE2_FLAGS
            cfgCmdList.append('sh')
            if binToBeCompiled == 'nspr':
                cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            else:
                cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append('--target=i686-pc-linux')
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append('--enable-address-sanitizer')
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        else:
            cfgCmdList.append('sh')
            if binToBeCompiled == 'nspr':
                cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            else:
                cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
    # 64-bit shell on Mac OS X 10.7 Lion and greater
    elif sps.isMac and sps.macVer() >= [10, 7] and not shell.buildOptions.enable32:
        if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
            cfgEnvDt['CC'] = CLANG_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
            cfgEnvDt['CXX'] = CLANGPP_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
        else:  # Uses system clang
            cfgEnvDt['CC'] = 'clang' + CLANG_PARAMS
            cfgEnvDt['CXX'] = 'clang++' + CLANG_PARAMS
        if sps.isProgramInstalled('brew'):
            cfgEnvDt['AUTOCONF'] = '/usr/local/Cellar/autoconf213/2.13/bin/autoconf213'
        cfgCmdList.append('sh')
        if binToBeCompiled == 'nspr':
            cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            cfgCmdList.append('--enable-64bit')
        else:
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        cfgCmdList.append('--target=x86_64-apple-darwin12.5.0')  # Mountain Lion 10.8.5
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append('--enable-address-sanitizer')
        if shell.buildOptions.enableSimulatorArm64:
            cfgCmdList.append('--enable-simulator=arm64')

    elif sps.isWin:
        cfgEnvDt['MAKE'] = 'mozmake'  # Workaround for bug 948534
        cfgCmdList.append('sh')
        if binToBeCompiled == 'nspr':
            cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            if shell.buildOptions.enable32:
                cfgCmdList.append('--enable-win32-target=WIN95')
            else:
                cfgCmdList.append('--enable-64bit')
        else:
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.enable32:
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        else:
            cfgCmdList.append('--host=x86_64-pc-mingw32')
            cfgCmdList.append('--target=x86_64-pc-mingw32')
            if shell.buildOptions.enableSimulatorArm64:
                cfgCmdList.append('--enable-simulator=arm64')
    else:
        # We might still be using GCC on Linux 64-bit, so do not use clang unless Asan is specified
        if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
            cfgEnvDt['CC'] = CLANG_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
            cfgEnvDt['CXX'] = CLANGPP_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
        cfgCmdList.append('sh')
        if binToBeCompiled == 'nspr':
            cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            cfgCmdList.append('--enable-64bit')
        else:
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append('--enable-address-sanitizer')

    if shell.buildOptions.buildWithAsan:
        assert 'clang' in cfgEnvDt['CC']
        assert 'clang++' in cfgEnvDt['CXX']
        cfgCmdList.append('--disable-jemalloc')  # See bug 1146895

    # For NSPR, specify "--disable-debug --enable-optimize" to generate an opt build.
    # They can actually be used independently, but it's not recommended.
    # https://developer.mozilla.org/en-US/docs/NSPR_build_instructions#Configure_options
    if shell.buildOptions.enableDbg:
        # NSPR configure without options compiles debug by default
        if binToBeCompiled == 'js':
            cfgCmdList.append('--enable-debug')
    elif shell.buildOptions.disableDbg or binToBeCompiled == 'nspr':
        cfgCmdList.append('--disable-debug')

    if shell.buildOptions.enableOpt:
        cfgCmdList.append('--enable-optimize' + ('=-O1' if shell.buildOptions.buildWithVg else ''))
    elif binToBeCompiled == 'js' and shell.buildOptions.disableOpt:
        # NSPR configure without options compiles debug by default
        cfgCmdList.append('--disable-optimize')

    if binToBeCompiled == 'nspr':
        cfgCmdList.append('--prefix=' +
                          sps.normExpUserPath(os.path.join(shell.getNsprObjdir(), 'dist')))
    else:
        if shell.buildOptions.enableProfiling:
            cfgCmdList.append('--enable-profiling')
        if shell.getJsUsesNoThreadsFlag() and shell.buildOptions.enableNsprBuild:
            cfgCmdList.append('--enable-nspr-build')
        else:
            if shell.buildOptions.enableNsprBuild:
                cfgCmdList.append('--enable-threadsafe')
                if not shell.getJsBuildSystemConsidersNspr():
                    cfgCmdList.append('--with-nspr-prefix=' +
                                      sps.normExpUserPath(os.path.join(shell.getNsprObjdir(), 'dist')))
                    cfgCmdList.append('--with-nspr-cflags=-I' +
                                      sps.normExpUserPath(os.path.join(shell.getNsprObjdir(), 'dist', 'include', 'nspr')))
                    cfgCmdList.append('--with-nspr-libs=' + ' '.join([
                        sps.normExpUserPath(os.path.join(shell.getNsprObjdir(), 'dist', 'lib',
                                                         compileLib))
                        for compileLib in inspectShell.ALL_COMPILE_LIBS
                        ]))
            else:
                cfgCmdList.append('--disable-threadsafe')

        if shell.buildOptions.enableMoreDeterministic:
            # Fuzzing tweaks for more useful output, implemented in bug 706433
            cfgCmdList.append('--enable-more-deterministic')

        if shell.buildOptions.buildWithVg:
            cfgCmdList.append('--enable-valgrind')
            cfgCmdList.append('--disable-jemalloc')

        # We add the following flags by default.
        if os.name == 'posix':
            cfgCmdList.append('--with-ccache')
        cfgCmdList.append('--enable-gczeal')
        cfgCmdList.append('--enable-debug-symbols')  # gets debug symbols on opt shells
        cfgCmdList.append('--disable-tests')

    if os.name == 'nt':
        # FIXME: Replace this with sps.shellify.
        counter = 0
        for entry in cfgCmdList:
            if os.sep in entry:
                assert sps.isWin  # MozillaBuild on Windows sometimes confuses "/" and "\".
                cfgCmdList[counter] = cfgCmdList[counter].replace(os.sep, '//')
            counter = counter + 1

    # Print whatever we added to the environment
    envVarList = []
    for envVar in set(cfgEnvDt.keys()) - set(origCfgEnvDt.keys()):
        strToBeAppended = envVar + '="' + cfgEnvDt[envVar] + '"' \
            if ' ' in cfgEnvDt[envVar] else envVar + '=' + cfgEnvDt[envVar]
        envVarList.append(strToBeAppended)
    sps.vdump('Command to be run is: ' + sps.shellify(envVarList) + ' ' + sps.shellify(cfgCmdList))

    wDir = shell.getNsprObjdir() if binToBeCompiled == 'nspr' else shell.getJsObjdir()
    assert os.path.isdir(wDir)

    if sps.isWin:
        changedCfgCmdList = []
        for entry in cfgCmdList:
            # See bug 986715 comment 6 as to why we need forward slashes for NSPR
            # For JS, quoted from :glandium: "the way icu subconfigure is called is what changed.
            #   but really, the whole thing likes forward slashes way better"
            # See bug 1038590 comment 9.
            if '\\' in entry:
                entry = entry.replace('\\', '/')
            changedCfgCmdList.append(entry)
        sps.captureStdout(changedCfgCmdList, ignoreStderr=True, currWorkingDir=wDir, env=cfgEnvDt)
    else:
        sps.captureStdout(cfgCmdList, ignoreStderr=True, currWorkingDir=wDir, env=cfgEnvDt)

    shell.setEnvAdded(envVarList)
    shell.setEnvFull(cfgEnvDt)
    shell.setCfgCmdExclEnv(cfgCmdList)
示例#19
0
def cfgBin(shell):
    """Configure a binary according to required parameters."""
    cfgCmdList = []
    cfgEnvDt = copy.deepcopy(os.environ)
    origCfgEnvDt = copy.deepcopy(os.environ)
    cfgEnvDt[b"AR"] = b"ar"
    if sps.isARMv7l:
        # 32-bit shell on ARM boards, e.g. odroid boards.
        # This is tested on Ubuntu 14.04 with necessary armel libraries (force)-installed.
        assert shell.buildOptions.enable32, 'arm7vl boards are only 32-bit, armv8 boards will be 64-bit.'
        if not shell.buildOptions.enableHardFp:
            cfgEnvDt[b"CC"] = b"gcc-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7"
            cfgEnvDt[b"CXX"] = b"g++-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7"
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        # From mjrosenb: things might go wrong if these three lines are not present for
        # compiling ARM on a 64-bit host machine. Not needed if compiling on the board itself.
        # cfgCmdList.append('--target=arm-linux-gnueabi')
        # cfgCmdList.append('--with-arch=armv7-a')
        # cfgCmdList.append('--with-thumb')
        if not shell.buildOptions.enableHardFp:
            cfgCmdList.append('--target=arm-linux-gnueabi')
    elif shell.buildOptions.enable32 and os.name == 'posix':
        # 32-bit shell on Mac OS X 10.10 Yosemite and greater
        if sps.isMac:
            assert sps.macVer() >= [10, 10]  # We no longer support 10.9 Mavericks and prior.
            # Uses system clang
            cfgEnvDt[b"CC"] = cfgEnvDt[b"HOST_CC"] = b"clang %s %s" % (CLANG_PARAMS, SSE2_FLAGS)
            cfgEnvDt[b"CXX"] = cfgEnvDt[b"HOST_CXX"] = b"clang++ %s %s" % (CLANG_PARAMS, SSE2_FLAGS)
            if shell.buildOptions.buildWithAsan:
                cfgEnvDt[b"CC"] += b" " + CLANG_ASAN_PARAMS
                cfgEnvDt[b"CXX"] += b" " + CLANG_ASAN_PARAMS
            cfgEnvDt[b"CC"] += b" " + CLANG_X86_FLAG  # only needed for CC, not HOST_CC
            cfgEnvDt[b"CXX"] += b" " + CLANG_X86_FLAG  # only needed for CXX, not HOST_CXX
            cfgEnvDt[b"RANLIB"] = b"ranlib"
            cfgEnvDt[b"AS"] = b"$CC"
            cfgEnvDt[b"LD"] = b"ld"
            cfgEnvDt[b"STRIP"] = b"strip -x -S"
            cfgEnvDt[b"CROSS_COMPILE"] = b"1"
            if sps.isProgramInstalled('brew'):
                cfgEnvDt[b"AUTOCONF"] = b"/usr/local/Cellar/autoconf213/2.13/bin/autoconf213"
                # Hacked up for new and old Homebrew configs, we can probably just call autoconf213
                if not os.path.isfile(sps.normExpUserPath(cfgEnvDt[b"AUTOCONF"])):
                    cfgEnvDt[b"AUTOCONF"] = b"autoconf213"
            cfgCmdList.append('sh')
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append('--target=i386-apple-darwin14.5.0')  # Yosemite 10.10.5
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append('--enable-address-sanitizer')
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                # Newer configure.in changes mean that things blow up if unknown/removed configure
                # options are entered, so specify it only if it's requested.
                if shell.buildOptions.enableArmSimulatorObsolete:
                    cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        # 32-bit shell on 32/64-bit x86 Linux
        elif sps.isLinux and not sps.isARMv7l:
            cfgEnvDt[b"PKG_CONFIG_LIBDIR"] = b"/usr/lib/pkgconfig"
            if shell.buildOptions.buildWithClang:
                cfgEnvDt[b"CC"] = cfgEnvDt[b"HOST_CC"] = str(
                    "clang %s %s %s" % (CLANG_PARAMS, SSE2_FLAGS, CLANG_X86_FLAG))
                cfgEnvDt[b"CXX"] = cfgEnvDt[b"HOST_CXX"] = str(
                    "clang++ %s %s %s" % (CLANG_PARAMS, SSE2_FLAGS, CLANG_X86_FLAG))
            else:
                # apt-get `lib32z1 gcc-multilib g++-multilib` first, if on 64-bit Linux.
                cfgEnvDt[b"CC"] = b"gcc -m32 %s" % SSE2_FLAGS
                cfgEnvDt[b"CXX"] = b"g++ -m32 %s" % SSE2_FLAGS
            if shell.buildOptions.buildWithAsan:
                cfgEnvDt[b"CC"] += b" " + CLANG_ASAN_PARAMS
                cfgEnvDt[b"CXX"] += b" " + CLANG_ASAN_PARAMS
            cfgCmdList.append('sh')
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append('--target=i686-pc-linux')
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append('--enable-address-sanitizer')
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                # Newer configure.in changes mean that things blow up if unknown/removed configure
                # options are entered, so specify it only if it's requested.
                if shell.buildOptions.enableArmSimulatorObsolete:
                    cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        else:
            cfgCmdList.append('sh')
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
    # 64-bit shell on Mac OS X 10.10 Yosemite and greater
    elif sps.isMac and sps.macVer() >= [10, 10] and not shell.buildOptions.enable32:
        cfgEnvDt[b"CC"] = b"clang " + CLANG_PARAMS
        cfgEnvDt[b"CXX"] = b"clang++ " + CLANG_PARAMS
        if shell.buildOptions.buildWithAsan:
            cfgEnvDt[b"CC"] += b" " + CLANG_ASAN_PARAMS
            cfgEnvDt[b"CXX"] += b" " + CLANG_ASAN_PARAMS
        if sps.isProgramInstalled('brew'):
            cfgEnvDt[b"AUTOCONF"] = b"/usr/local/Cellar/autoconf213/2.13/bin/autoconf213"
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        cfgCmdList.append('--target=x86_64-apple-darwin14.5.0')  # Yosemite 10.10.5
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append('--enable-address-sanitizer')
        if shell.buildOptions.enableSimulatorArm64:
            cfgCmdList.append('--enable-simulator=arm64')

    elif sps.isWin:
        cfgEnvDt[b"MAKE"] = b"mozmake"  # Workaround for bug 948534
        if shell.buildOptions.buildWithClang:
            cfgEnvDt[b"CC"] = b"clang-cl.exe " + CLANG_PARAMS
            cfgEnvDt[b"CXX"] = b"clang-cl.exe " + CLANG_PARAMS
        if shell.buildOptions.buildWithAsan:
            cfgEnvDt[b"CFLAGS"] = CLANG_ASAN_PARAMS
            cfgEnvDt[b"CXXFLAGS"] = CLANG_ASAN_PARAMS
            cfgEnvDt[b"LDFLAGS"] = (b"clang_rt.asan_dynamic-x86_64.lib "
                                    b"clang_rt.asan_dynamic_runtime_thunk-x86_64.lib "
                                    b"clang_rt.asan_dynamic-x86_64.dll")
            cfgEnvDt[b"HOST_CFLAGS"] = b" "
            cfgEnvDt[b"HOST_CXXFLAGS"] = b" "
            cfgEnvDt[b"HOST_LDFLAGS"] = b" "
            cfgEnvDt[b"LIB"] += br"C:\Program Files\LLVM\lib\clang\4.0.0\lib\windows"
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.enable32:
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                # Newer configure.in changes mean that things blow up if unknown/removed configure
                # options are entered, so specify it only if it's requested.
                if shell.buildOptions.enableArmSimulatorObsolete:
                    cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        else:
            cfgCmdList.append('--host=x86_64-pc-mingw32')
            cfgCmdList.append('--target=x86_64-pc-mingw32')
            if shell.buildOptions.enableSimulatorArm64:
                cfgCmdList.append('--enable-simulator=arm64')
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append('--enable-address-sanitizer')
    else:
        # We might still be using GCC on Linux 64-bit, so do not use clang unless Asan is specified
        if shell.buildOptions.buildWithClang:
            cfgEnvDt[b"CC"] = b"clang " + CLANG_PARAMS
            cfgEnvDt[b"CXX"] = b"clang++ " + CLANG_PARAMS
        if shell.buildOptions.buildWithAsan:
            cfgEnvDt[b"CC"] += b" " + CLANG_ASAN_PARAMS
            cfgEnvDt[b"CXX"] += b" " + CLANG_ASAN_PARAMS
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append('--enable-address-sanitizer')

    if shell.buildOptions.buildWithClang:
        if sps.isWin:
            assert b"clang-cl" in cfgEnvDt[b"CC"]
            assert b"clang-cl" in cfgEnvDt[b"CXX"]
        else:
            assert b"clang" in cfgEnvDt[b"CC"]
            assert b"clang++" in cfgEnvDt[b"CXX"]
        cfgCmdList.append('--disable-jemalloc')  # See bug 1146895

    if shell.buildOptions.enableDbg:
        cfgCmdList.append('--enable-debug')
    elif shell.buildOptions.disableDbg:
        cfgCmdList.append('--disable-debug')

    if shell.buildOptions.enableOpt:
        cfgCmdList.append('--enable-optimize' + ('=-O1' if shell.buildOptions.buildWithVg else ''))
    elif shell.buildOptions.disableOpt:
        cfgCmdList.append('--disable-optimize')
    if shell.buildOptions.enableProfiling:  # Now obsolete, retained for backward compatibility
        cfgCmdList.append('--enable-profiling')
    if shell.buildOptions.disableProfiling:
        cfgCmdList.append('--disable-profiling')

    if shell.buildOptions.enableMoreDeterministic:
        # Fuzzing tweaks for more useful output, implemented in bug 706433
        cfgCmdList.append('--enable-more-deterministic')
    if shell.buildOptions.enableOomBreakpoint:  # Extra debugging help for OOM assertions
        cfgCmdList.append('--enable-oom-breakpoint')
    if shell.buildOptions.enableWithoutIntlApi:  # Speeds up compilation but is non-default
        cfgCmdList.append('--without-intl-api')

    if shell.buildOptions.buildWithVg:
        cfgCmdList.append('--enable-valgrind')
        cfgCmdList.append('--disable-jemalloc')

    # We add the following flags by default.
    if os.name == 'posix':
        cfgCmdList.append('--with-ccache')
    cfgCmdList.append('--enable-gczeal')
    cfgCmdList.append('--enable-debug-symbols')  # gets debug symbols on opt shells
    cfgCmdList.append('--disable-tests')

    if os.name == 'nt':
        # FIXME: Replace this with sps.shellify.
        counter = 0
        for entry in cfgCmdList:
            if os.sep in entry:
                assert sps.isWin  # MozillaBuild on Windows sometimes confuses "/" and "\".
                cfgCmdList[counter] = cfgCmdList[counter].replace(os.sep, '//')
            counter = counter + 1

    # Print whatever we added to the environment
    envVarList = []
    for envVar in set(cfgEnvDt.keys()) - set(origCfgEnvDt.keys()):
        strToBeAppended = str(envVar + '="' + cfgEnvDt[str(envVar)] +
                              '"' if " " in cfgEnvDt[str(envVar)] else envVar +
                              "=" + cfgEnvDt[str(envVar)])
        envVarList.append(strToBeAppended)
    sps.vdump('Command to be run is: ' + sps.shellify(envVarList) + ' ' + sps.shellify(cfgCmdList))

    wDir = shell.getJsObjdir()
    assert os.path.isdir(wDir)

    if sps.isWin:
        changedCfgCmdList = []
        for entry in cfgCmdList:
            # For JS, quoted from :glandium: "the way icu subconfigure is called is what changed.
            #   but really, the whole thing likes forward slashes way better"
            # See bug 1038590 comment 9.
            if '\\' in entry:
                entry = entry.replace('\\', '/')
            changedCfgCmdList.append(entry)
        sps.captureStdout(changedCfgCmdList, ignoreStderr=True, currWorkingDir=wDir, env=cfgEnvDt)
    else:
        sps.captureStdout(cfgCmdList, ignoreStderr=True, currWorkingDir=wDir, env=cfgEnvDt)

    shell.setEnvAdded(envVarList)
    shell.setEnvFull(cfgEnvDt)
    shell.setCfgCmdExclEnv(cfgCmdList)
示例#20
0
def bisectUsingTboxBins(options):
    """Download treeherder binaries and bisect them."""
    testedIDs = {}
    desiredArch = '32' if options.buildOptions.enable32 else '64'
    buildType = downloadBuild.defaultBuildType(options.nameOfTreeherderBranch,
                                               desiredArch,
                                               options.buildOptions.enableDbg)

    # Get list of treeherder IDs
    urlsTbox = downloadBuild.getBuildList(buildType,
                                          earliestBuild=options.startRepo,
                                          latestBuild=options.endRepo)

    # Download and test starting point.
    print '\nExamining starting point...'
    sID, startResult, _sReason, _sPosition, urlsTbox, testedIDs, _startSkippedNum = testBuildOrNeighbour(
        options, 0, urlsTbox, buildType, testedIDs)
    if sID is None:
        raise Exception('No complete builds were found.')
    print 'Numeric ID ' + sID + ' was tested.'

    # Download and test ending point.
    print '\nExamining ending point...'
    eID, endResult, _eReason, _ePosition, urlsTbox, testedIDs, _endSkippedNum = testBuildOrNeighbour(
        options,
        len(urlsTbox) - 1, urlsTbox, buildType, testedIDs)
    if eID is None:
        raise Exception('No complete builds were found.')
    print 'Numeric ID ' + eID + ' was tested.'

    if startResult == endResult:
        raise Exception(
            'Starting and ending points should have opposite results')

    count = 0
    print '\nStarting bisection...\n'
    while count < MAX_ITERATIONS:
        sps.vdump('Unsorted dictionary of tested IDs is: ' + str(testedIDs))
        count += 1
        print 'Test number ' + str(count) + ':'

        sortedUrlsTbox = sorted(urlsTbox)
        if len(sortedUrlsTbox) >= 3:
            mPosition = len(sortedUrlsTbox) // 2
        else:
            print '\nWARNING: ' + str(sortedUrlsTbox) + ' has size smaller than 3. ' + \
                'Impossible to return "middle" element.\n'
            mPosition = len(sortedUrlsTbox)

        # Test the middle revision. If it is not a complete build, test ones around it.
        mID, mResult, _mReason, mPosition, urlsTbox, testedIDs, middleRevSkippedNum = testBuildOrNeighbour(
            options, mPosition, urlsTbox, buildType, testedIDs)
        if mID is None:
            print 'Middle ID is None.'
            break

        # Refresh the range of treeherder IDs depending on mResult.
        if mResult == endResult:
            urlsTbox = urlsTbox[0:(mPosition + 1)]
        else:
            urlsTbox = urlsTbox[(mPosition):len(urlsTbox)]

        print 'Numeric ID ' + mID + ' was tested.',

        #  Exit infinite loop once we have tested the starting point, ending point and any points
        #  in the middle with results returning "incomplete".
        if (len(urlsTbox) - middleRevSkippedNum) <= 2 and mID in testedIDs:
            break
        elif len(urlsTbox) < 2:
            print 'urlsTbox is: ' + str(urlsTbox)
            raise Exception('Length of urlsTbox should not be smaller than 2.')
        elif (len(testedIDs) - 2) > 30:
            raise Exception('Number of testedIDs has exceeded 30.')

        print showRemainingNumOfTests(urlsTbox)

    print
    sps.vdump('Build URLs are: ' + str(urlsTbox))
    assert getIdFromTboxUrl(
        urlsTbox[0]) in testedIDs, 'Starting ID should have been tested.'
    assert getIdFromTboxUrl(
        urlsTbox[-1]) in testedIDs, 'Ending ID should have been tested.'
    outputTboxBisectionResults(options, urlsTbox, testedIDs)
示例#21
0
def findBlamedCset(options, repoDir, testRev):
    print "%s | Bisecting on: %s" % (sps.dateStr(), repoDir)

    hgPrefix = ['hg', '-R', repoDir]

    # Resolve names such as "tip", "default", or "52707" to stable hg hash ids, e.g. "9f2641871ce8".
    realStartRepo = sRepo = hgCmds.getRepoHashAndId(
        repoDir, repoRev=options.startRepo)[0]
    realEndRepo = eRepo = hgCmds.getRepoHashAndId(repoDir,
                                                  repoRev=options.endRepo)[0]
    sps.vdump("Bisecting in the range " + sRepo + ":" + eRepo)

    # Refresh source directory (overwrite all local changes) to default tip if required.
    if options.resetRepoFirst:
        subprocess.check_call(hgPrefix + ['update', '-C', 'default'])
        # Throws exit code 255 if purge extension is not enabled in .hgrc:
        subprocess.check_call(hgPrefix + ['purge', '--all'])

    # Reset bisect ranges and set skip ranges.
    sps.captureStdout(hgPrefix + ['bisect', '-r'])
    if options.skipRevs:
        sps.captureStdout(hgPrefix + ['bisect', '--skip', options.skipRevs])

    labels = {}
    # Specify `hg bisect` ranges.
    if options.testInitialRevs:
        currRev = eRepo  # If testInitialRevs mode is set, compile and test the latest rev first.
    else:
        labels[sRepo] = ('good', 'assumed start rev is good')
        labels[eRepo] = ('bad', 'assumed end rev is bad')
        subprocess.check_call(hgPrefix + ['bisect', '-U', '-g', sRepo])
        currRev = hgCmds.getCsetHashFromBisectMsg(
            fileManipulation.firstLine(
                sps.captureStdout(hgPrefix +
                                  ['bisect', '-U', '-b', eRepo])[0]))

    iterNum = 1
    if options.testInitialRevs:
        iterNum -= 2

    skipCount = 0
    blamedRev = None

    while currRev is not None:
        startTime = time.time()
        label = testRev(currRev)
        labels[currRev] = label
        if label[0] == 'skip':
            skipCount += 1
            # If we use "skip", we tell hg bisect to do a linear search to get around the skipping.
            # If the range is large, doing a bisect to find the start and endpoints of compilation
            # bustage would be faster. 20 total skips being roughly the time that the pair of
            # bisections would take.
            if skipCount > 20:
                print 'Skipped 20 times, stopping autoBisect.'
                break
        print label[0] + " (" + label[1] + ") ",

        if iterNum <= 0:
            print 'Finished testing the initial boundary revisions...',
        else:
            print "Bisecting for the n-th round where n is", iterNum, "and 2^n is", \
                  str(2**iterNum), "...",
        (blamedGoodOrBad, blamedRev, currRev, sRepo, eRepo) = \
            bisectLabel(hgPrefix, options, label[0], currRev, sRepo, eRepo)

        if options.testInitialRevs:
            options.testInitialRevs = False
            assert currRev is None
            currRev = sRepo  # If options.testInitialRevs is set, test earliest possible rev next.

        iterNum += 1
        endTime = time.time()
        oneRunTime = endTime - startTime
        print 'This iteration took %.3f seconds to run.' % oneRunTime

    if blamedRev is not None:
        checkBlameParents(repoDir, blamedRev, blamedGoodOrBad, labels, testRev,
                          realStartRepo, realEndRepo)

    sps.vdump("Resetting bisect")
    subprocess.check_call(hgPrefix + ['bisect', '-U', '-r'])

    sps.vdump("Resetting working directory")
    sps.captureStdout(hgPrefix + ['update', '-C', '-r', 'default'],
                      ignoreStderr=True)
    hgCmds.destroyPyc(repoDir)

    print sps.dateStr()
示例#22
0
def testBinary(shell,
               file,
               flagsRequired,
               valgSupport,
               verbose=False,
               timeout=None):
    testBinaryCmd = [shell] + flagsRequired + [file]
    if valgSupport:
        valgPrefixCmd = []
        valgPrefixCmd.append('valgrind')
        if platform.system() == 'Darwin':
            valgPrefixCmd.append('--dsymutil=yes')
        valgPrefixCmd.append('--smc-check=all-non-file')
        valgPrefixCmd.append('--leak-check=full')
        testBinaryCmd = valgPrefixCmd + testBinaryCmd
    vdump('The testing command is:' + ' '.join(testBinaryCmd))

    # Capture stdout and stderr into the same string.
    p = subprocess.Popen(testBinaryCmd,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)

    (out, err) = ('', '')
    retCode = 0

    if (timeout != None):
        signal.signal(signal.SIGALRM, alarm_handler)
        signal.alarm(timeout)  # 5 minutes
    try:
        out, err = p.communicate()
        signal.alarm(0)
        retCode = p.returncode
    except Alarm:
        p.terminate()

    if verbose:
        print 'The exit code is:', retCode
        if len(out) > 0:
            print 'stdout shows:', out
        if len(err) > 0:
            print 'stderr shows:', err

    # Switch to interactive input mode similar to `cat testcase.js | ./js -j -i`.
    # Doesn't work, stdout shows:
    #can't open : No such file or directory
    #The exit code is: 4
    #The second output is: None
    #if retCode == 0:
    #    # Append the quit() function to make the testcase quit.
    #    # Doesn't work if retCode is something other than 0, that watchExitCode specified.
    #    testcaseFile = open(file, 'a')
    #    testcaseFile.write('\nquit()\n')
    #    testcaseFile.close()
    #
    #    # Test interactive input.
    #    print 'Switching to interactive input mode in case passing as a CLI ' + \
    #            'argument does not reproduce the issue..'
    #    testBinaryCmd3 = subprocess.Popen([shell, methodJit, tracingJit, '-i'],
    #        stdin=(subprocess.Popen(['cat', file])).stdout)
    #    output2 = testBinaryCmd3.communicate()[0]
    #    retCode = testBinaryCmd3.returncode
    #    print 'The exit code is:', retCode
    #    print 'The second output is:', output2
    return out + "\n" + err, retCode
示例#23
0
def bisectUsingTboxBins(options):
    '''
    Downloads treeherder binaries and bisects them.
    '''
    testedIDs = {}
    desiredArch = '32' if options.buildOptions.enable32 else '64'
    buildType = downloadBuild.defaultBuildType(options.nameOfTreeherderBranch, desiredArch, options.buildOptions.enableDbg)

    # Get list of treeherder IDs
    urlsTbox = downloadBuild.getBuildList(buildType, earliestBuild=options.startRepo, latestBuild=options.endRepo)

    # Download and test starting point.
    print '\nExamining starting point...'
    sID, startResult, sReason, sPosition, urlsTbox, testedIDs, startSkippedNum = testBuildOrNeighbour(
        options, 0, urlsTbox, buildType, testedIDs)
    if sID is None:
        raise Exception('No complete builds were found.')
    print 'Numeric ID ' + sID + ' was tested.'

    # Download and test ending point.
    print '\nExamining ending point...'
    eID, endResult, eReason, ePosition, urlsTbox, testedIDs, endSkippedNum = testBuildOrNeighbour(
        options, len(urlsTbox) - 1, urlsTbox, buildType, testedIDs)
    if eID is None:
        raise Exception('No complete builds were found.')
    print 'Numeric ID ' + eID + ' was tested.'

    if startResult == endResult:
        raise Exception('Starting and ending points should have opposite results')

    count = 0
    print '\nStarting bisection...\n'
    while count < MAX_ITERATIONS:
        sps.vdump('Unsorted dictionary of tested IDs is: ' + str(testedIDs))
        count += 1
        print 'Test number ' + str(count) + ':'

        sortedUrlsTbox = sorted(urlsTbox)
        if len(sortedUrlsTbox) >= 3:
            mPosition = len(sortedUrlsTbox) // 2
        else:
            print '\nWARNING: ' + str(sortedUrlsTbox) + ' has size smaller than 3. ' + \
                'Impossible to return "middle" element.\n'
            mPosition = len(sortedUrlsTbox)

        # Test the middle revision. If it is not a complete build, test ones around it.
        mID, mResult, mReason, mPosition, urlsTbox, testedIDs, middleRevSkippedNum = testBuildOrNeighbour(
            options, mPosition, urlsTbox, buildType, testedIDs)
        if mID is None:
            print 'Middle ID is None.'
            break

        # Refresh the range of treeherder IDs depending on mResult.
        if mResult == endResult:
            urlsTbox = urlsTbox[0:(mPosition + 1)]
        else:
            urlsTbox = urlsTbox[(mPosition):len(urlsTbox)]

        print 'Numeric ID ' + mID + ' was tested.',

        #  Exit infinite loop once we have tested the starting point, ending point and any points
        #  in the middle with results returning "incomplete".
        if (len(urlsTbox) - middleRevSkippedNum) <= 2 and mID in testedIDs:
            break
        elif len(urlsTbox) < 2:
            print 'urlsTbox is: ' + str(urlsTbox)
            raise Exception('Length of urlsTbox should not be smaller than 2.')
        elif (len(testedIDs) - 2) > 30:
            raise Exception('Number of testedIDs has exceeded 30.')

        print showRemainingNumOfTests(urlsTbox)

    print
    sps.vdump('Build URLs are: ' + str(urlsTbox))
    assert getIdFromTboxUrl(urlsTbox[0]) in testedIDs, 'Starting ID should have been tested.'
    assert getIdFromTboxUrl(urlsTbox[-1]) in testedIDs, 'Ending ID should have been tested.'
    outputTboxBisectionResults(options, urlsTbox, testedIDs)
示例#24
0
def cfgBin(shell):
    """This function configures a binary according to required parameters."""
    cfgCmdList = []
    cfgEnvDt = copy.deepcopy(os.environ)
    origCfgEnvDt = copy.deepcopy(os.environ)
    cfgEnvDt["AR"] = "ar"
    # Check for determinism to prevent LLVM compilation from happening on releng machines,
    # since releng machines only test non-deterministic builds.
    if shell.buildOptions.buildWithAsan and shell.buildOptions.enableMoreDeterministic:
        llvmPath = envVars.findLlvmBinPath()
        assert llvmPath is not None
        CLANG_PATH = sps.normExpUserPath(os.path.join(llvmPath, "clang"))
        CLANGPP_PATH = sps.normExpUserPath(os.path.join(llvmPath, "clang++"))

    if sps.isARMv7l:
        # 32-bit shell on ARM boards, e.g. odroid boards.
        # This is tested on Ubuntu 14.04 with necessary armel libraries (force)-installed.
        assert shell.buildOptions.enable32, "arm7vl boards are only 32-bit, armv8 boards will be 64-bit."
        if not shell.buildOptions.enableHardFp:
            cfgEnvDt["CC"] = "gcc-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7"
            cfgEnvDt["CXX"] = "g++-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7"
        cfgCmdList.append("sh")
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        # From mjrosenb: things might go wrong if these three lines are not present for
        # compiling ARM on a 64-bit host machine. Not needed if compiling on the board itself.
        # cfgCmdList.append('--target=arm-linux-gnueabi')
        # cfgCmdList.append('--with-arch=armv7-a')
        # cfgCmdList.append('--with-thumb')
        if not shell.buildOptions.enableHardFp:
            cfgCmdList.append("--target=arm-linux-gnueabi")
    elif shell.buildOptions.enable32 and os.name == "posix":
        # 32-bit shell on Mac OS X 10.7 Lion and greater
        if sps.isMac:
            assert sps.macVer() >= [10, 7]  # We no longer support Snow Leopard 10.6 and prior.
            if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
                cfgEnvDt["CC"] = cfgEnvDt["HOST_CC"] = CLANG_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS + SSE2_FLAGS
                cfgEnvDt["CXX"] = cfgEnvDt["HOST_CXX"] = CLANGPP_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS + SSE2_FLAGS
            else:  # Uses system clang
                cfgEnvDt["CC"] = cfgEnvDt["HOST_CC"] = "clang" + CLANG_PARAMS + SSE2_FLAGS
                cfgEnvDt["CXX"] = cfgEnvDt["HOST_CXX"] = "clang++" + CLANG_PARAMS + SSE2_FLAGS
            cfgEnvDt["CC"] = cfgEnvDt["CC"] + CLANG_X86_FLAG  # only needed for CC, not HOST_CC
            cfgEnvDt["CXX"] = cfgEnvDt["CXX"] + CLANG_X86_FLAG  # only needed for CXX, not HOST_CXX
            cfgEnvDt["RANLIB"] = "ranlib"
            cfgEnvDt["AS"] = "$CC"
            cfgEnvDt["LD"] = "ld"
            cfgEnvDt["STRIP"] = "strip -x -S"
            cfgEnvDt["CROSS_COMPILE"] = "1"
            if sps.isProgramInstalled("brew"):
                cfgEnvDt["AUTOCONF"] = "/usr/local/Cellar/autoconf213/2.13/bin/autoconf213"
            cfgCmdList.append("sh")
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append("--target=i386-apple-darwin9.2.0")  # Leopard 10.5.2
            cfgCmdList.append("--enable-macos-target=10.5")
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append("--enable-address-sanitizer")
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                cfgCmdList.append("--enable-arm-simulator")
                cfgCmdList.append("--enable-simulator=arm")
        # 32-bit shell on 32/64-bit x86 Linux
        elif sps.isLinux and not sps.isARMv7l:
            cfgEnvDt["PKG_CONFIG_LIBDIR"] = "/usr/lib/pkgconfig"
            if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
                cfgEnvDt["CC"] = cfgEnvDt["HOST_CC"] = (
                    CLANG_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS + SSE2_FLAGS + CLANG_X86_FLAG
                )
                cfgEnvDt["CXX"] = cfgEnvDt["HOST_CXX"] = (
                    CLANGPP_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS + SSE2_FLAGS + CLANG_X86_FLAG
                )
            else:  # Uses system clang
                # We might still be using GCC on Linux 32-bit, use clang only if we specify ASan
                # apt-get `lib32z1 gcc-multilib g++-multilib` first, if on 64-bit Linux.
                cfgEnvDt["CC"] = "gcc -m32" + SSE2_FLAGS
                cfgEnvDt["CXX"] = "g++ -m32" + SSE2_FLAGS
            cfgCmdList.append("sh")
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append("--target=i686-pc-linux")
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append("--enable-address-sanitizer")
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                cfgCmdList.append("--enable-arm-simulator")
                cfgCmdList.append("--enable-simulator=arm")
        else:
            cfgCmdList.append("sh")
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
    # 64-bit shell on Mac OS X 10.7 Lion and greater
    elif sps.isMac and sps.macVer() >= [10, 7] and not shell.buildOptions.enable32:
        if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
            cfgEnvDt["CC"] = CLANG_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
            cfgEnvDt["CXX"] = CLANGPP_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
        else:  # Uses system clang
            cfgEnvDt["CC"] = "clang" + CLANG_PARAMS
            cfgEnvDt["CXX"] = "clang++" + CLANG_PARAMS
        if sps.isProgramInstalled("brew"):
            cfgEnvDt["AUTOCONF"] = "/usr/local/Cellar/autoconf213/2.13/bin/autoconf213"
        cfgCmdList.append("sh")
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        cfgCmdList.append("--target=x86_64-apple-darwin12.5.0")  # Mountain Lion 10.8.5
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append("--enable-address-sanitizer")
        if shell.buildOptions.enableSimulatorArm64:
            cfgCmdList.append("--enable-simulator=arm64")

    elif sps.isWin:
        cfgEnvDt["MAKE"] = "mozmake"  # Workaround for bug 948534
        cfgCmdList.append("sh")
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.enable32:
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                cfgCmdList.append("--enable-arm-simulator")
                cfgCmdList.append("--enable-simulator=arm")
        else:
            cfgCmdList.append("--host=x86_64-pc-mingw32")
            cfgCmdList.append("--target=x86_64-pc-mingw32")
            if shell.buildOptions.enableSimulatorArm64:
                cfgCmdList.append("--enable-simulator=arm64")
    else:
        # We might still be using GCC on Linux 64-bit, so do not use clang unless Asan is specified
        if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
            cfgEnvDt["CC"] = CLANG_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
            cfgEnvDt["CXX"] = CLANGPP_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
        cfgCmdList.append("sh")
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append("--enable-address-sanitizer")

    if shell.buildOptions.buildWithAsan:
        assert "clang" in cfgEnvDt["CC"]
        assert "clang++" in cfgEnvDt["CXX"]
        cfgCmdList.append("--disable-jemalloc")  # See bug 1146895

    if shell.buildOptions.enableDbg:
        cfgCmdList.append("--enable-debug")
    elif shell.buildOptions.disableDbg:
        cfgCmdList.append("--disable-debug")

    if shell.buildOptions.enableOpt:
        cfgCmdList.append("--enable-optimize" + ("=-O1" if shell.buildOptions.buildWithVg else ""))
    elif shell.buildOptions.disableOpt:
        cfgCmdList.append("--disable-optimize")
    if shell.buildOptions.enableProfiling:
        cfgCmdList.append("--enable-profiling")

    if shell.buildOptions.enableMoreDeterministic:
        # Fuzzing tweaks for more useful output, implemented in bug 706433
        cfgCmdList.append("--enable-more-deterministic")
    if shell.buildOptions.enableOomBreakpoint:  # Extra debugging help for OOM assertions
        cfgCmdList.append("--enable-oom-breakpoint")
    if shell.buildOptions.enableWithoutIntlApi:  # Speeds up compilation but is non-default
        cfgCmdList.append("--without-intl-api")

    if shell.buildOptions.buildWithVg:
        cfgCmdList.append("--enable-valgrind")
        cfgCmdList.append("--disable-jemalloc")

    # We add the following flags by default.
    if os.name == "posix":
        cfgCmdList.append("--with-ccache")
    cfgCmdList.append("--enable-gczeal")
    cfgCmdList.append("--enable-debug-symbols")  # gets debug symbols on opt shells
    cfgCmdList.append("--disable-tests")

    if os.name == "nt":
        # FIXME: Replace this with sps.shellify.
        counter = 0
        for entry in cfgCmdList:
            if os.sep in entry:
                assert sps.isWin  # MozillaBuild on Windows sometimes confuses "/" and "\".
                cfgCmdList[counter] = cfgCmdList[counter].replace(os.sep, "//")
            counter = counter + 1

    # Print whatever we added to the environment
    envVarList = []
    for envVar in set(cfgEnvDt.keys()) - set(origCfgEnvDt.keys()):
        strToBeAppended = (
            envVar + '="' + cfgEnvDt[envVar] + '"' if " " in cfgEnvDt[envVar] else envVar + "=" + cfgEnvDt[envVar]
        )
        envVarList.append(strToBeAppended)
    sps.vdump("Command to be run is: " + sps.shellify(envVarList) + " " + sps.shellify(cfgCmdList))

    wDir = shell.getJsObjdir()
    assert os.path.isdir(wDir)

    if sps.isWin:
        changedCfgCmdList = []
        for entry in cfgCmdList:
            # For JS, quoted from :glandium: "the way icu subconfigure is called is what changed.
            #   but really, the whole thing likes forward slashes way better"
            # See bug 1038590 comment 9.
            if "\\" in entry:
                entry = entry.replace("\\", "/")
            changedCfgCmdList.append(entry)
        sps.captureStdout(changedCfgCmdList, ignoreStderr=True, currWorkingDir=wDir, env=cfgEnvDt)
    else:
        sps.captureStdout(cfgCmdList, ignoreStderr=True, currWorkingDir=wDir, env=cfgEnvDt)

    shell.setEnvAdded(envVarList)
    shell.setEnvFull(cfgEnvDt)
    shell.setCfgCmdExclEnv(cfgCmdList)
示例#25
0
def findBlamedCset(options, repoDir, testRev):
    print sps.dateStr()

    hgPrefix = ['hg', '-R', repoDir]

    # Resolve names such as "tip", "default", or "52707" to stable hg hash ids, e.g. "9f2641871ce8".
    realStartRepo = sRepo = hgCmds.getRepoHashAndId(repoDir, repoRev=options.startRepo)[0]
    realEndRepo = eRepo = hgCmds.getRepoHashAndId(repoDir, repoRev=options.endRepo)[0]
    sps.vdump("Bisecting in the range " + sRepo + ":" + eRepo)

    # Refresh source directory (overwrite all local changes) to default tip if required.
    if options.resetRepoFirst:
        subprocess.check_call(hgPrefix + ['update', '-C', 'default'])
        # Throws exit code 255 if purge extension is not enabled in .hgrc:
        subprocess.check_call(hgPrefix + ['purge', '--all'])

    # Reset bisect ranges and set skip ranges.
    sps.captureStdout(hgPrefix + ['bisect', '-r'])
    if options.skipRevs:
        sps.captureStdout(hgPrefix + ['bisect', '--skip', options.skipRevs])

    labels = {}
    # Specify `hg bisect` ranges.
    if options.testInitialRevs:
        currRev = eRepo  # If testInitialRevs mode is set, compile and test the latest rev first.
    else:
        labels[sRepo] = ('good', 'assumed start rev is good')
        labels[eRepo] = ('bad', 'assumed end rev is bad')
        subprocess.check_call(hgPrefix + ['bisect', '-U', '-g', sRepo])
        currRev = hgCmds.getCsetHashFromBisectMsg(fileManipulation.firstLine(
            sps.captureStdout(hgPrefix + ['bisect', '-U', '-b', eRepo])[0]))

    iterNum = 1
    if options.testInitialRevs:
        iterNum -= 2

    skipCount = 0
    blamedRev = None

    while currRev is not None:
        startTime = time.time()
        label = testRev(currRev)
        labels[currRev] = label
        if label[0] == 'skip':
            skipCount += 1
            # If we use "skip", we tell hg bisect to do a linear search to get around the skipping.
            # If the range is large, doing a bisect to find the start and endpoints of compilation
            # bustage would be faster. 20 total skips being roughly the time that the pair of
            # bisections would take.
            if skipCount > 20:
                print 'Skipped 20 times, stopping autoBisect.'
                break
        print label[0] + " (" + label[1] + ") ",

        if iterNum <= 0:
            print 'Finished testing the initial boundary revisions...',
        else:
            print "Bisecting for the n-th round where n is", iterNum, "and 2^n is", \
                  str(2**iterNum), "...",
        (blamedGoodOrBad, blamedRev, currRev, sRepo, eRepo) = \
            bisectLabel(hgPrefix, options, label[0], currRev, sRepo, eRepo)

        if options.testInitialRevs:
            options.testInitialRevs = False
            assert currRev is None
            currRev = sRepo  # If options.testInitialRevs is set, test earliest possible rev next.

        iterNum += 1
        endTime = time.time()
        oneRunTime = endTime - startTime
        print 'This iteration took %.3f seconds to run.' % oneRunTime

    if blamedRev is not None:
        checkBlameParents(repoDir, blamedRev, blamedGoodOrBad, labels, testRev, realStartRepo,
                          realEndRepo)

    sps.vdump("Resetting bisect")
    subprocess.check_call(hgPrefix + ['bisect', '-U', '-r'])

    sps.vdump("Resetting working directory")
    sps.captureStdout(hgPrefix + ['update', '-C', '-r', 'default'], ignoreStderr=True)
    hgCmds.destroyPyc(repoDir)

    print sps.dateStr()
示例#26
0
def jsfunfuzzLevel(options, logPrefix, quiet=False):
    (lev, issues, runinfo) = baseLevel(
        options.jsengineWithArgs, options.timeout, options.knownPath, logPrefix, valgrind=options.valgrind
    )

    if lev == JS_FINE:
        # Check for unexplained exits and for jsfunfuzz saying "Found a bug".
        understoodExit = False

        # Read in binary mode, because otherwise Python on Windows will
        # throw a fit when it encounters certain unicode.  Note that this
        # makes line endings platform-specific.

        if "-dm-" in options.jsengineWithArgs[0]:
            # Since this is an --enable-more-deterministic build, we should get messages on stderr
            # if the shell quit() or terminate() functions are called.
            # (We use a sketchy filename-matching check because it's faster than inspecting the binary.)
            with open(logPrefix + "-err.txt", "rb") as f:
                for line in f:
                    if "terminate called" in line or "quit called" in line:
                        understoodExit = True
                    if "can't allocate region" in line:
                        understoodExit = True
        else:
            understoodExit = True

        with open(logPrefix + "-out.txt", "rb") as f:
            for line in f:
                if line.startswith("It's looking good!") or line.startswith(
                    "jsfunfuzz broke its own scripting environment: "
                ):
                    understoodExit = True
                if line.startswith("Found a bug: "):
                    understoodExit = True
                    if not ("NestTest" in line and oomed(logPrefix)):
                        lev = JS_DECIDED_TO_EXIT
                        issues.append(line.rstrip())
                        # FIXME: if not quiet:
                        # FIXME:     output everything between this line and "jsfunfuzz stopping due to finding a bug."

        if not understoodExit:
            issues.append("jsfunfuzz didn't finish")
            lev = JS_DID_NOT_FINISH

    # FIXME: if not quiet:
    # FIXME:     output the last tryItOut line

    if lev <= JS_ABNORMAL_EXIT:  # JS_ABNORMAL_EXIT and below (inclusive) will be ignored.
        sps.vdump("jsfunfuzzLevel is ignoring a baseLevel of " + str(lev))
        lev = JS_FINE
        issues = []

    if lev != JS_FINE:
        # FIXME: compareJIT failures do not generate this -summary file.
        statusIssueList = []
        for i in issues:
            statusIssueList.append("Status: " + i)
        assert len(statusIssueList) != 0
        fileManipulation.writeLinesToFile(
            ["Number: " + logPrefix + "\n", "Command: " + sps.shellify(options.jsengineWithArgs) + "\n"]
            + [i + "\n" for i in statusIssueList],
            logPrefix + "-summary.txt",
        )

    if not quiet:
        print logPrefix + " | " + summaryString(issues, lev, runinfo.elapsedtime)
    return lev
示例#27
0
def jsfunfuzzLevel(options, logPrefix, quiet=False):
    (lev, issues, runinfo) = baseLevel(options.jsengineWithArgs,
                                       options.timeout,
                                       options.knownPath,
                                       logPrefix,
                                       valgrind=options.valgrind)

    if lev == JS_FINE:
        # Check for unexplained exits and for jsfunfuzz saying "Found a bug".
        understoodExit = False

        # Read in binary mode, because otherwise Python on Windows will
        # throw a fit when it encounters certain unicode.  Note that this
        # makes line endings platform-specific.

        if '-dm-' in options.jsengineWithArgs[0]:
            # Since this is an --enable-more-deterministic build, we should get messages on stderr
            # if the shell quit() or terminate() functions are called.
            # (We use a sketchy filename-matching check because it's faster than inspecting the binary.)
            with open(logPrefix + "-err.txt", "rb") as f:
                for line in f:
                    if "terminate called" in line or "quit called" in line:
                        understoodExit = True
                    if "can't allocate region" in line:
                        understoodExit = True
        else:
            understoodExit = True

        with open(logPrefix + "-out.txt", "rb") as f:
            for line in f:
                if line.startswith("It's looking good!") or line.startswith(
                        "jsfunfuzz broke its own scripting environment: "):
                    understoodExit = True
                if line.startswith("Found a bug: "):
                    understoodExit = True
                    if not ("NestTest" in line and oomed(logPrefix)):
                        lev = JS_DECIDED_TO_EXIT
                        issues.append(line.rstrip())
                        # FIXME: if not quiet:
                        # FIXME:     output everything between this line and "jsfunfuzz stopping due to finding a bug."

        if not understoodExit:
            issues.append("jsfunfuzz didn't finish")
            lev = JS_DID_NOT_FINISH

    # FIXME: if not quiet:
    # FIXME:     output the last tryItOut line

    if lev <= JS_ABNORMAL_EXIT:  # JS_ABNORMAL_EXIT and below (inclusive) will be ignored.
        sps.vdump("jsfunfuzzLevel is ignoring a baseLevel of " + str(lev))
        lev = JS_FINE
        issues = []

    if lev != JS_FINE:
        # FIXME: compareJIT failures do not generate this -summary file.
        statusIssueList = []
        for i in issues:
            statusIssueList.append('Status: ' + i)
        assert len(statusIssueList) != 0
        fileManipulation.writeLinesToFile([
            'Number: ' + logPrefix + '\n',
            'Command: ' + sps.shellify(options.jsengineWithArgs) + '\n'
        ] + [i + '\n' for i in statusIssueList], logPrefix + '-summary.txt')

    if not quiet:
        print logPrefix + " | " + summaryString(issues, lev,
                                                runinfo.elapsedtime)
    return lev
示例#28
0
def cfgBin(shell):
    """Configure a binary according to required parameters."""
    cfgCmdList = []
    cfgEnvDt = copy.deepcopy(os.environ)
    origCfgEnvDt = copy.deepcopy(os.environ)
    cfgEnvDt['AR'] = 'ar'
    if sps.isARMv7l:
        # 32-bit shell on ARM boards, e.g. odroid boards.
        # This is tested on Ubuntu 14.04 with necessary armel libraries (force)-installed.
        assert shell.buildOptions.enable32, 'arm7vl boards are only 32-bit, armv8 boards will be 64-bit.'
        if not shell.buildOptions.enableHardFp:
            cfgEnvDt['CC'] = 'gcc-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7'
            cfgEnvDt['CXX'] = 'g++-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7'
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        # From mjrosenb: things might go wrong if these three lines are not present for
        # compiling ARM on a 64-bit host machine. Not needed if compiling on the board itself.
        # cfgCmdList.append('--target=arm-linux-gnueabi')
        # cfgCmdList.append('--with-arch=armv7-a')
        # cfgCmdList.append('--with-thumb')
        if not shell.buildOptions.enableHardFp:
            cfgCmdList.append('--target=arm-linux-gnueabi')
    elif shell.buildOptions.enable32 and os.name == 'posix':
        # 32-bit shell on Mac OS X 10.10 Yosemite and greater
        if sps.isMac:
            assert sps.macVer() >= [10, 10]  # We no longer support 10.9 Mavericks and prior.
            # Uses system clang
            cfgEnvDt['CC'] = cfgEnvDt['HOST_CC'] = 'clang' + CLANG_PARAMS + SSE2_FLAGS
            cfgEnvDt['CXX'] = cfgEnvDt['HOST_CXX'] = 'clang++' + CLANG_PARAMS + SSE2_FLAGS
            if shell.buildOptions.buildWithAsan:
                cfgEnvDt['CC'] += CLANG_ASAN_PARAMS
                cfgEnvDt['CXX'] += CLANG_ASAN_PARAMS
            cfgEnvDt['CC'] = cfgEnvDt['CC'] + CLANG_X86_FLAG  # only needed for CC, not HOST_CC
            cfgEnvDt['CXX'] = cfgEnvDt['CXX'] + CLANG_X86_FLAG  # only needed for CXX, not HOST_CXX
            cfgEnvDt['RANLIB'] = 'ranlib'
            cfgEnvDt['AS'] = '$CC'
            cfgEnvDt['LD'] = 'ld'
            cfgEnvDt['STRIP'] = 'strip -x -S'
            cfgEnvDt['CROSS_COMPILE'] = '1'
            if sps.isProgramInstalled('brew'):
                cfgEnvDt['AUTOCONF'] = '/usr/local/Cellar/autoconf213/2.13/bin/autoconf213'
            cfgCmdList.append('sh')
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append('--target=i386-apple-darwin14.5.0')  # Yosemite 10.10.5
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append('--enable-address-sanitizer')
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                # Newer configure.in changes mean that things blow up if unknown/removed configure
                # options are entered, so specify it only if it's requested.
                if shell.buildOptions.enableArmSimulatorObsolete:
                    cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        # 32-bit shell on 32/64-bit x86 Linux
        elif sps.isLinux and not sps.isARMv7l:
            cfgEnvDt['PKG_CONFIG_LIBDIR'] = '/usr/lib/pkgconfig'
            if shell.buildOptions.buildWithClang:
                cfgEnvDt['CC'] = cfgEnvDt['HOST_CC'] = 'clang' + CLANG_PARAMS + SSE2_FLAGS + CLANG_X86_FLAG
                cfgEnvDt['CXX'] = cfgEnvDt['HOST_CXX'] = 'clang++' + CLANG_PARAMS + SSE2_FLAGS + CLANG_X86_FLAG
            else:
                # apt-get `lib32z1 gcc-multilib g++-multilib` first, if on 64-bit Linux.
                cfgEnvDt['CC'] = 'gcc -m32' + SSE2_FLAGS
                cfgEnvDt['CXX'] = 'g++ -m32' + SSE2_FLAGS
            if shell.buildOptions.buildWithAsan:
                cfgEnvDt['CC'] += CLANG_ASAN_PARAMS
                cfgEnvDt['CXX'] += CLANG_ASAN_PARAMS
            cfgCmdList.append('sh')
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append('--target=i686-pc-linux')
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append('--enable-address-sanitizer')
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                # Newer configure.in changes mean that things blow up if unknown/removed configure
                # options are entered, so specify it only if it's requested.
                if shell.buildOptions.enableArmSimulatorObsolete:
                    cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        else:
            cfgCmdList.append('sh')
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
    # 64-bit shell on Mac OS X 10.10 Yosemite and greater
    elif sps.isMac and sps.macVer() >= [10, 10] and not shell.buildOptions.enable32:
        cfgEnvDt['CC'] = 'clang' + CLANG_PARAMS
        cfgEnvDt['CXX'] = 'clang++' + CLANG_PARAMS
        if shell.buildOptions.buildWithAsan:
            cfgEnvDt['CC'] += CLANG_ASAN_PARAMS
            cfgEnvDt['CXX'] += CLANG_ASAN_PARAMS
        if sps.isProgramInstalled('brew'):
            cfgEnvDt['AUTOCONF'] = '/usr/local/Cellar/autoconf213/2.13/bin/autoconf213'
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        cfgCmdList.append('--target=x86_64-apple-darwin14.5.0')  # Yosemite 10.10.5
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append('--enable-address-sanitizer')
        if shell.buildOptions.enableSimulatorArm64:
            cfgCmdList.append('--enable-simulator=arm64')

    elif sps.isWin:
        cfgEnvDt['MAKE'] = 'mozmake'  # Workaround for bug 948534
        if shell.buildOptions.buildWithClang:
            cfgEnvDt['CC'] = 'clang-cl.exe' + CLANG_PARAMS
            cfgEnvDt['CXX'] = 'clang-cl.exe' + CLANG_PARAMS
        # Note: Doesn't seem to work yet.
        # if shell.buildOptions.buildWithAsan:
        #     cfgEnvDt['CC'] += CLANG_ASAN_PARAMS
        #     cfgEnvDt['CXX'] += CLANG_ASAN_PARAMS
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.enable32:
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                # Newer configure.in changes mean that things blow up if unknown/removed configure
                # options are entered, so specify it only if it's requested.
                if shell.buildOptions.enableArmSimulatorObsolete:
                    cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        else:
            cfgCmdList.append('--host=x86_64-pc-mingw32')
            cfgCmdList.append('--target=x86_64-pc-mingw32')
            if shell.buildOptions.enableSimulatorArm64:
                cfgCmdList.append('--enable-simulator=arm64')
        # Note: Doesn't seem to work yet.
        # if shell.buildOptions.buildWithAsan:
        #     cfgCmdList.append('--enable-address-sanitizer')
    else:
        # We might still be using GCC on Linux 64-bit, so do not use clang unless Asan is specified
        if shell.buildOptions.buildWithClang:
            cfgEnvDt['CC'] = 'clang' + CLANG_PARAMS
            cfgEnvDt['CXX'] = 'clang++' + CLANG_PARAMS
        if shell.buildOptions.buildWithAsan:
            cfgEnvDt['CC'] += CLANG_ASAN_PARAMS
            cfgEnvDt['CXX'] += CLANG_ASAN_PARAMS
        cfgCmdList.append('sh')
        cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append('--enable-address-sanitizer')

    if shell.buildOptions.buildWithClang:
        if sps.isWin:
            assert 'clang-cl' in cfgEnvDt['CC']
            assert 'clang-cl' in cfgEnvDt['CXX']
        else:
            assert 'clang' in cfgEnvDt['CC']
            assert 'clang++' in cfgEnvDt['CXX']
        cfgCmdList.append('--disable-jemalloc')  # See bug 1146895

    if shell.buildOptions.enableDbg:
        cfgCmdList.append('--enable-debug')
    elif shell.buildOptions.disableDbg:
        cfgCmdList.append('--disable-debug')

    if shell.buildOptions.enableOpt:
        cfgCmdList.append('--enable-optimize' + ('=-O1' if shell.buildOptions.buildWithVg else ''))
    elif shell.buildOptions.disableOpt:
        cfgCmdList.append('--disable-optimize')
    if shell.buildOptions.enableProfiling:
        cfgCmdList.append('--enable-profiling')

    if shell.buildOptions.enableMoreDeterministic:
        # Fuzzing tweaks for more useful output, implemented in bug 706433
        cfgCmdList.append('--enable-more-deterministic')
    if shell.buildOptions.enableOomBreakpoint:  # Extra debugging help for OOM assertions
        cfgCmdList.append('--enable-oom-breakpoint')
    if shell.buildOptions.enableWithoutIntlApi:  # Speeds up compilation but is non-default
        cfgCmdList.append('--without-intl-api')

    if shell.buildOptions.buildWithVg:
        cfgCmdList.append('--enable-valgrind')
        cfgCmdList.append('--disable-jemalloc')

    # We add the following flags by default.
    if os.name == 'posix':
        cfgCmdList.append('--with-ccache')
    cfgCmdList.append('--enable-gczeal')
    cfgCmdList.append('--enable-debug-symbols')  # gets debug symbols on opt shells
    cfgCmdList.append('--disable-tests')

    if os.name == 'nt':
        # FIXME: Replace this with sps.shellify.
        counter = 0
        for entry in cfgCmdList:
            if os.sep in entry:
                assert sps.isWin  # MozillaBuild on Windows sometimes confuses "/" and "\".
                cfgCmdList[counter] = cfgCmdList[counter].replace(os.sep, '//')
            counter = counter + 1

    # Print whatever we added to the environment
    envVarList = []
    for envVar in set(cfgEnvDt.keys()) - set(origCfgEnvDt.keys()):
        strToBeAppended = envVar + '="' + cfgEnvDt[envVar] + '"' \
            if ' ' in cfgEnvDt[envVar] else envVar + '=' + cfgEnvDt[envVar]
        envVarList.append(strToBeAppended)
    sps.vdump('Command to be run is: ' + sps.shellify(envVarList) + ' ' + sps.shellify(cfgCmdList))

    wDir = shell.getJsObjdir()
    assert os.path.isdir(wDir)

    if sps.isWin:
        changedCfgCmdList = []
        for entry in cfgCmdList:
            # For JS, quoted from :glandium: "the way icu subconfigure is called is what changed.
            #   but really, the whole thing likes forward slashes way better"
            # See bug 1038590 comment 9.
            if '\\' in entry:
                entry = entry.replace('\\', '/')
            changedCfgCmdList.append(entry)
        sps.captureStdout(changedCfgCmdList, ignoreStderr=True, currWorkingDir=wDir, env=cfgEnvDt)
    else:
        sps.captureStdout(cfgCmdList, ignoreStderr=True, currWorkingDir=wDir, env=cfgEnvDt)

    shell.setEnvAdded(envVarList)
    shell.setEnvFull(cfgEnvDt)
    shell.setCfgCmdExclEnv(cfgCmdList)
示例#29
0
def cfgBin(shell, binToBeCompiled):
    '''This function configures a binary according to required parameters.'''
    cfgCmdList = []
    cfgEnvDt = copy.deepcopy(os.environ)
    origCfgEnvDt = copy.deepcopy(os.environ)
    cfgEnvDt['AR'] = 'ar'
    # Check for determinism to prevent LLVM compilation from happening on releng machines,
    # since releng machines only test non-deterministic builds.
    if shell.buildOptions.buildWithAsan and shell.buildOptions.enableMoreDeterministic:
        llvmPath = envVars.findLlvmBinPath()
        assert llvmPath is not None
        CLANG_PATH = sps.normExpUserPath(os.path.join(llvmPath, 'clang'))
        CLANGPP_PATH = sps.normExpUserPath(os.path.join(llvmPath, 'clang++'))

    if sps.isARMv7l:
        # 32-bit shell on ARM boards, e.g. odroid boards.
        # This is tested on Ubuntu 14.04 with necessary armel libraries (force)-installed.
        assert shell.buildOptions.enable32, 'arm7vl boards are only 32-bit, armv8 boards will be 64-bit.'
        if not shell.buildOptions.enableHardFp:
            cfgEnvDt[
                'CC'] = 'gcc-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7'
            cfgEnvDt[
                'CXX'] = 'g++-4.7 -mfloat-abi=softfp -B/usr/lib/gcc/arm-linux-gnueabi/4.7'
        cfgCmdList.append('sh')
        if binToBeCompiled == 'nspr':
            cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
        else:
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            # From mjrosenb: things might go wrong if these three lines are not present for
            # compiling ARM on a 64-bit host machine. Not needed if compiling on the board itself.
            # cfgCmdList.append('--target=arm-linux-gnueabi')
            # cfgCmdList.append('--with-arch=armv7-a')
            # cfgCmdList.append('--with-thumb')
        if not shell.buildOptions.enableHardFp:
            cfgCmdList.append('--target=arm-linux-gnueabi')
    elif shell.buildOptions.enable32 and os.name == 'posix':
        # 32-bit shell on Mac OS X 10.7 Lion and greater
        if sps.isMac:
            assert sps.macVer() >= [
                10, 7
            ]  # We no longer support Snow Leopard 10.6 and prior.
            if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
                cfgEnvDt['CC'] = cfgEnvDt['HOST_CC'] = CLANG_PATH + CLANG_PARAMS + \
                    CLANG_ASAN_PARAMS + SSE2_FLAGS
                cfgEnvDt['CXX'] = cfgEnvDt['HOST_CXX'] = CLANGPP_PATH + CLANG_PARAMS + \
                    CLANG_ASAN_PARAMS + SSE2_FLAGS
            else:  # Uses system clang
                cfgEnvDt['CC'] = cfgEnvDt[
                    'HOST_CC'] = 'clang' + CLANG_PARAMS + SSE2_FLAGS
                cfgEnvDt['CXX'] = cfgEnvDt[
                    'HOST_CXX'] = 'clang++' + CLANG_PARAMS + SSE2_FLAGS
            cfgEnvDt['CC'] = cfgEnvDt[
                'CC'] + CLANG_X86_FLAG  # only needed for CC, not HOST_CC
            cfgEnvDt['CXX'] = cfgEnvDt[
                'CXX'] + CLANG_X86_FLAG  # only needed for CXX, not HOST_CXX
            cfgEnvDt['RANLIB'] = 'ranlib'
            cfgEnvDt['AS'] = '$CC'
            cfgEnvDt['LD'] = 'ld'
            cfgEnvDt['STRIP'] = 'strip -x -S'
            cfgEnvDt['CROSS_COMPILE'] = '1'
            if sps.isProgramInstalled('brew'):
                cfgEnvDt[
                    'AUTOCONF'] = '/usr/local/Cellar/autoconf213/2.13/bin/autoconf213'
            cfgCmdList.append('sh')
            if binToBeCompiled == 'nspr':
                cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            else:
                cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append(
                '--target=i386-apple-darwin9.2.0')  # Leopard 10.5.2
            cfgCmdList.append('--enable-macos-target=10.5')
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append('--enable-address-sanitizer')
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        # 32-bit shell on 32/64-bit x86 Linux
        elif sps.isLinux and not sps.isARMv7l:
            cfgEnvDt['PKG_CONFIG_LIBDIR'] = '/usr/lib/pkgconfig'
            if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
                cfgEnvDt['CC'] = cfgEnvDt['HOST_CC'] = CLANG_PATH + CLANG_PARAMS + \
                    CLANG_ASAN_PARAMS + SSE2_FLAGS + CLANG_X86_FLAG
                cfgEnvDt['CXX'] = cfgEnvDt['HOST_CXX'] = CLANGPP_PATH + CLANG_PARAMS + \
                    CLANG_ASAN_PARAMS + SSE2_FLAGS + CLANG_X86_FLAG
            else:  # Uses system clang
                # We might still be using GCC on Linux 32-bit, use clang only if we specify ASan
                # apt-get `lib32z1 gcc-multilib g++-multilib` first, if on 64-bit Linux.
                cfgEnvDt['CC'] = 'gcc -m32' + SSE2_FLAGS
                cfgEnvDt['CXX'] = 'g++ -m32' + SSE2_FLAGS
            cfgCmdList.append('sh')
            if binToBeCompiled == 'nspr':
                cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            else:
                cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
            cfgCmdList.append('--target=i686-pc-linux')
            if shell.buildOptions.buildWithAsan:
                cfgCmdList.append('--enable-address-sanitizer')
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        else:
            cfgCmdList.append('sh')
            if binToBeCompiled == 'nspr':
                cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            else:
                cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
    # 64-bit shell on Mac OS X 10.7 Lion and greater
    elif sps.isMac and sps.macVer() >= [10, 7
                                        ] and not shell.buildOptions.enable32:
        if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
            cfgEnvDt['CC'] = CLANG_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
            cfgEnvDt['CXX'] = CLANGPP_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
        else:  # Uses system clang
            cfgEnvDt['CC'] = 'clang' + CLANG_PARAMS
            cfgEnvDt['CXX'] = 'clang++' + CLANG_PARAMS
        if sps.isProgramInstalled('brew'):
            cfgEnvDt[
                'AUTOCONF'] = '/usr/local/Cellar/autoconf213/2.13/bin/autoconf213'
        cfgCmdList.append('sh')
        if binToBeCompiled == 'nspr':
            cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            cfgCmdList.append('--enable-64bit')
        else:
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        cfgCmdList.append(
            '--target=x86_64-apple-darwin12.5.0')  # Mountain Lion 10.8.5
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append('--enable-address-sanitizer')
        if shell.buildOptions.enableSimulatorArm64:
            cfgCmdList.append('--enable-simulator=arm64')

    elif sps.isWin:
        cfgEnvDt['MAKE'] = 'mozmake'  # Workaround for bug 948534
        cfgCmdList.append('sh')
        if binToBeCompiled == 'nspr':
            cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            if shell.buildOptions.enable32:
                cfgCmdList.append('--enable-win32-target=WIN95')
            else:
                cfgCmdList.append('--enable-64bit')
        else:
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.enable32:
            if shell.buildOptions.enableSimulatorArm32:
                # --enable-arm-simulator became --enable-simulator=arm in rev 25e99bc12482
                # but unknown flags are ignored, so we compile using both till Fx38 ESR is deprecated
                cfgCmdList.append('--enable-arm-simulator')
                cfgCmdList.append('--enable-simulator=arm')
        else:
            cfgCmdList.append('--host=x86_64-pc-mingw32')
            cfgCmdList.append('--target=x86_64-pc-mingw32')
            if shell.buildOptions.enableSimulatorArm64:
                cfgCmdList.append('--enable-simulator=arm64')
    else:
        # We might still be using GCC on Linux 64-bit, so do not use clang unless Asan is specified
        if shell.buildOptions.buildWithAsan:  # Uses custom compiled clang
            cfgEnvDt['CC'] = CLANG_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
            cfgEnvDt['CXX'] = CLANGPP_PATH + CLANG_PARAMS + CLANG_ASAN_PARAMS
        cfgCmdList.append('sh')
        if binToBeCompiled == 'nspr':
            cfgCmdList.append(os.path.normpath(shell.getNsprCfgPath()))
            cfgCmdList.append('--enable-64bit')
        else:
            cfgCmdList.append(os.path.normpath(shell.getJsCfgPath()))
        if shell.buildOptions.buildWithAsan:
            cfgCmdList.append('--enable-address-sanitizer')

    if shell.buildOptions.buildWithAsan:
        assert 'clang' in cfgEnvDt['CC']
        assert 'clang++' in cfgEnvDt['CXX']
        cfgCmdList.append('--disable-jemalloc')  # See bug 1146895

    # For NSPR, specify "--disable-debug --enable-optimize" to generate an opt build.
    # They can actually be used independently, but it's not recommended.
    # https://developer.mozilla.org/en-US/docs/NSPR_build_instructions#Configure_options
    if shell.buildOptions.enableDbg:
        # NSPR configure without options compiles debug by default
        if binToBeCompiled == 'js':
            cfgCmdList.append('--enable-debug')
    elif shell.buildOptions.disableDbg or binToBeCompiled == 'nspr':
        cfgCmdList.append('--disable-debug')

    if shell.buildOptions.enableOpt:
        cfgCmdList.append('--enable-optimize' +
                          ('=-O1' if shell.buildOptions.buildWithVg else ''))
    elif binToBeCompiled == 'js' and shell.buildOptions.disableOpt:
        # NSPR configure without options compiles debug by default
        cfgCmdList.append('--disable-optimize')

    if binToBeCompiled == 'nspr':
        cfgCmdList.append(
            '--prefix=' +
            sps.normExpUserPath(os.path.join(shell.getNsprObjdir(), 'dist')))
    else:
        if shell.buildOptions.enableProfiling:
            cfgCmdList.append('--enable-profiling')
        if shell.getJsUsesNoThreadsFlag(
        ) and shell.buildOptions.enableNsprBuild:
            cfgCmdList.append('--enable-nspr-build')
        else:
            if shell.buildOptions.enableNsprBuild:
                cfgCmdList.append('--enable-threadsafe')
                if not shell.getJsBuildSystemConsidersNspr():
                    cfgCmdList.append(
                        '--with-nspr-prefix=' + sps.normExpUserPath(
                            os.path.join(shell.getNsprObjdir(), 'dist')))
                    cfgCmdList.append('--with-nspr-cflags=-I' +
                                      sps.normExpUserPath(
                                          os.path.join(shell.getNsprObjdir(
                                          ), 'dist', 'include', 'nspr')))
                    cfgCmdList.append('--with-nspr-libs=' + ' '.join([
                        sps.normExpUserPath(
                            os.path.join(shell.getNsprObjdir(), 'dist', 'lib',
                                         compileLib))
                        for compileLib in inspectShell.ALL_COMPILE_LIBS
                    ]))
            else:
                cfgCmdList.append('--disable-threadsafe')

        if shell.buildOptions.enableMoreDeterministic:
            # Fuzzing tweaks for more useful output, implemented in bug 706433
            cfgCmdList.append('--enable-more-deterministic')

        if shell.buildOptions.buildWithVg:
            cfgCmdList.append('--enable-valgrind')
            cfgCmdList.append('--disable-jemalloc')

        # We add the following flags by default.
        if os.name == 'posix':
            cfgCmdList.append('--with-ccache')
        cfgCmdList.append('--enable-gczeal')
        cfgCmdList.append(
            '--enable-debug-symbols')  # gets debug symbols on opt shells
        cfgCmdList.append('--disable-tests')

    if os.name == 'nt':
        # FIXME: Replace this with sps.shellify.
        counter = 0
        for entry in cfgCmdList:
            if os.sep in entry:
                assert sps.isWin  # MozillaBuild on Windows sometimes confuses "/" and "\".
                cfgCmdList[counter] = cfgCmdList[counter].replace(os.sep, '//')
            counter = counter + 1

    # Print whatever we added to the environment
    envVarList = []
    for envVar in set(cfgEnvDt.keys()) - set(origCfgEnvDt.keys()):
        strToBeAppended = envVar + '="' + cfgEnvDt[envVar] + '"' \
            if ' ' in cfgEnvDt[envVar] else envVar + '=' + cfgEnvDt[envVar]
        envVarList.append(strToBeAppended)
    sps.vdump('Command to be run is: ' + sps.shellify(envVarList) + ' ' +
              sps.shellify(cfgCmdList))

    wDir = shell.getNsprObjdir(
    ) if binToBeCompiled == 'nspr' else shell.getJsObjdir()
    assert os.path.isdir(wDir)

    if sps.isWin:
        changedCfgCmdList = []
        for entry in cfgCmdList:
            # See bug 986715 comment 6 as to why we need forward slashes for NSPR
            # For JS, quoted from :glandium: "the way icu subconfigure is called is what changed.
            #   but really, the whole thing likes forward slashes way better"
            # See bug 1038590 comment 9.
            if '\\' in entry:
                entry = entry.replace('\\', '/')
            changedCfgCmdList.append(entry)
        sps.captureStdout(changedCfgCmdList,
                          ignoreStderr=True,
                          currWorkingDir=wDir,
                          env=cfgEnvDt)
    else:
        sps.captureStdout(cfgCmdList,
                          ignoreStderr=True,
                          currWorkingDir=wDir,
                          env=cfgEnvDt)

    shell.setEnvAdded(envVarList)
    shell.setEnvFull(cfgEnvDt)
    shell.setCfgCmdExclEnv(cfgCmdList)