Ejemplo n.º 1
0
def convertCppFileForInvGen(cppFile, outFile):
    with NamedTemporaryFile(suffix=".cpp", delete=False) as processedF:
        # First strip #includes and add a int NONDET;
        badLinesRe = re.compile("(^#include.*$)|" + "int unknown[0-9]\(\);|" +
                                "int __VERIFIER_nondet_int\(\);|" +
                                "unsigned int __VERIFIER_nondet_uint\(\);|" +
                                "_Bool __VERIFIER_nondet_bool\(\);")
        noNondetIntAssign = re.compile(" *= *__VERIFIER_nondet_int *\(\)")
        noNondetUIntAssign = re.compile(" *= *__VERIFIER_nondet_uint *\(\)")
        substStar = re.compile("while *\( *\* *\)")
        lines = open(cppFile).read().split("\n")
        lines = [l for l in lines if not badLinesRe.match(l)]
        lines = ["//Auto-generated by " + __file__ + " from " + cppFile ] + \
                ["int NONDET;"] + lines
        lines = [noNondetIntAssign.sub("", l) for l in lines]
        lines = [noNondetUIntAssign.sub("", l) for l in lines]
        lines = [substStar.sub("while(NONDET)", l) for l in lines]
        processedF.write("\n".join(lines))
        processedF.flush()

        error("De-included file in ", processedF.name)
        cpp_args = [
            "cpp", "-D_Static_assert=assert", "-D_static_assert=assert",
            "-Dstatic_assert=assert", "-D__VERIFIER_assert=assert",
            "-D__VERIFIER_assume=assume", "-Dunknown1()=NONDET",
            "-Dunknown2()=NONDET", "-Dunknown3()=NONDET",
            "-Dunknown4()=NONDET", "-Dunknown5()=NONDET",
            "-DLARGE_INT=2147483647", "-D__VERIFIER_nondet_int()=NONDET",
            processedF.name, outFile
        ]

        call(cpp_args, stderr=STDOUT)
        error("CPP-ed file in ", outFile)
Ejemplo n.º 2
0
def runDaikon(varz: List[str], trace: List[List[BoogieVal]], nosuppress: bool=False) -> List[AstExpr]:
  with NamedTemporaryFile(suffix=".dtrace", delete=False, mode="w") as dtraceF:
    dtraceF.write(toDaikonTrace(varz,trace));
    dtraceF.flush();
    args = ["java", "daikon.Daikon"]
    if (nosuppress):
      # Lets disable all filters and enable all invariants
      args = args + \
        flattenList([[ "--config_option", x + "=false" ] \
                        for x in filter_opts]) + \
        flattenList([[ "--config_option", x + "=true" ] \
                        for x in inv_enable_opts])
    args.append(dtraceF.name)
    raw = check_output(args).decode()
    call(["rm", basename(dtraceF.name)[:-len(".dtrace")]+".inv.gz"])
    start = raw.index("LoopEntry:::") + len("LoopEntry:::")
    end = raw.index("Exiting Daikon.", start)
    invs = [x for x in [x.strip() for x in raw[start:end].split("\n")] if x != ""]
    # I don't understand how LinearTeranry invariants without justification are
    # displayed... Also getting lazy to fix the long line..
    invs = [x for x in invs if "warning: too few samples for daikon.inv.ternary.threeScalar.LinearTernary invariant" not in x]; #pylint: disable=line-too-long
    invs = [x for x in invs if "(mod 0)" not in x];
    parsable = []
    for i in invs:
      try:
        parsable.append(parseExprAst(i));
      except Exception:
        error("Failed parsing: ", i)
    return parsable
Ejemplo n.º 3
0
def runInvGen(cppFile, mainRoutine):
    with NamedTemporaryFile(suffix=".front.out", delete=False) as frontOut,\
         NamedTemporaryFile(suffix=".invgen.out", delete=False) as invgenOut,\
         NamedTemporaryFile(suffix=".pl", delete=False) as transitionsF:
        if isfile(INVGEN_PATH + "/frontend"):
            frontendName = "/frontend"
        else:
            frontendName = "/frontend.exe"
        if isfile(INVGEN_PATH + "/invgen"):
            invgenName = "/invgen"
        else:
            invgenName = "/invgen.exe"

        args = [
            INVGEN_PATH + frontendName, "-main", mainRoutine, cppFile, "-o",
            transitionsF.name
        ]
        error("Frontend output in ", frontOut.name)
        try:
            check_call(args, stderr=STDOUT, stdout=frontOut)
        except CalledProcessError as e:
            raw = open(frontOut.name).read()
            outp = raw.split("\n")
            if outp[-2] == "Fatal error: exception ArmcStmt.NotImplemented(\"Mod\")":
                return ("NYI: Mod", [], outp)
            elif "Fatal error:" in raw and "Not implemented (unsigned int" in raw:
                return ("NYI: Unsigned Int Cast", [], outp)
            elif outp[-2] == "Fatal error: exception Failure(\"Push Negation failed! I am here!\")":  #pylint: disable=line-too-long
                return ("Frontend Crash", [], outp)
            raise e

        error("Transitions file in ", transitionsF.name)
        args = [INVGEN_PATH + invgenName, transitionsF.name]
        error("Invgen output in ", invgenOut.name)
        try:
            raw = check_output(args, stderr=STDOUT)
        except CalledProcessError as e:
            outp = e.output.split("\n")
            if outp[-2] == "! 'All direct(loop free) path to error are unsat'":
                return ("InvGen Crash", [], outp)
            elif outp[-2] == "! pred2coeff('Bad Predicate')":
                return ("InvGen Crash", [], outp)
            raise e
        lines = raw.split("\n")

        while (lines[-1] == ''):
            lines.pop()

        solved = lines[-1].startswith("#Total Solving time:")
        invgenOut.write("\n".join(lines))
        invgenOut.flush()
        if (solved):
            invRe = re.compile("^[^\[]*\[(?P<invs>[^\]]*)\]$")
            invariants = invRe.match(lines[-2]).groupdict()["invs"].split(",")
        else:
            invariants = []

        return (solved, invariants, lines)
Ejemplo n.º 4
0
def loadLvlSet(lvlSetFile: str) -> Tuple[str, Dict[str, FlowgameLevel]]:
    # Small helper funct to make sure we didn't
    # accidentally give two levels the same name
    def assertUniqueKeys(kvs):
        keys = [x[0] for x in kvs]
        assert (len(set(keys)) == len(keys))
        return dict(kvs)

    lvlSet = load(open(lvlSetFile, "r"), object_pairs_hook=assertUniqueKeys)
    lvlSetDir = dirname(abspath(realpath(lvlSetFile)))
    error("Loading level set " + lvlSet["name"] + " from " + lvlSetFile)
    lvls: Dict[str, FlowgameLevel] = OrderedDict()
    for t in lvlSet["levels"]:
        lvlName = t[0]
        lvlPath = t[1]

        for i in range(len(lvlPath)):
            lvlPath[i] = join(lvlSetDir, lvlPath[i])

        error("Loading level: ", lvlPath[0])
        fun = FlowgameLevel.load(lvlPath[0], lvlName)
        lvls[lvlName] = fun

    return (lvlSet["name"], lvls)
Ejemplo n.º 5
0
def loadBoogieLvlSet(lvlSetFile: str) -> Tuple[str, Dict[str, BoogieTraceLvl]]:
    # Small helper funct to make sure we didn't
    # accidentally give two levels the same name
    def assertUniqueKeys(kvs):
        keys = [x[0] for x in kvs]
        assert (len(set(keys)) == len(keys))
        return dict(kvs)

    lvlSet = load(open(lvlSetFile, "r"), object_pairs_hook=assertUniqueKeys)
    lvlSetDir = dirname(abspath(realpath(lvlSetFile)))
    error("Loading level set " + lvlSet["name"] + " from " + lvlSetFile)
    lvls: Dict[str, BoogieTraceLvl] = OrderedDict()
    for t in lvlSet["levels"]:
        lvlName = t[0]
        lvlPath = t[1]

        for i in range(len(lvlPath)):
            lvlPath[i] = join(lvlSetDir, lvlPath[i])

        error("Loading level: ", lvlPath[0])
        lvl = loadBoogieFile(lvlPath[0])
        lvl["path"] = lvlPath

        if (len(t) > 2):
            splitterPreds = [parseExprAst(exp) for exp in t[2]]
            splitterPred = ast_and(splitterPreds)
            remainderInv = parseExprAst(t[3])

            lvl['data'][0] = [
                row for row in lvl['data'][0]
                if eval_quick(splitterPred,
                              {k: v
                               for k, v in zip(lvl['variables'], row)})
            ]

            if (len(lvl['data'][0]) == 0):
                error("SKIPPING : ", lvlName, " due to no filtered rows.")
                continue

            lvl['partialInv'] = remainderInv
            lvl['splitterPreds'] = splitterPreds

        lvls[lvlName] = lvl

    return (lvlSet["name"], lvls)
Ejemplo n.º 6
0
def runInvGen(cppFile, mainRoutine):
  with NamedTemporaryFile(suffix=".front.out", delete=False) as frontOut,\
       NamedTemporaryFile(suffix=".invgen.out", delete=False) as invgenOut,\
       NamedTemporaryFile(suffix=".pl", delete=False) as transitionsF:
    if isfile(INVGEN_PATH + "/frontend"):
      frontendName = "/frontend"
    else:
      frontendName = "/frontend.exe"
    if isfile(INVGEN_PATH + "/invgen"):
      invgenName = "/invgen"
    else:
      invgenName = "/invgen.exe"

    args = [ INVGEN_PATH + frontendName,
              "-main", mainRoutine,
              cppFile,
              "-o", transitionsF.name]
    error("Frontend output in ", frontOut.name)
    try:
      check_call(args, stderr=STDOUT, stdout=frontOut);
    except CalledProcessError,e:
      raw = open(frontOut.name).read();
      outp = raw.split("\n")
      if outp[-2] == "Fatal error: exception ArmcStmt.NotImplemented(\"Mod\")":
        return ("NYI: Mod", [], outp)
      elif "Fatal error:" in raw and "Not implemented (unsigned int" in raw:
        return ("NYI: Unsigned Int Cast", [], outp)
      elif outp[-2] == "Fatal error: exception Failure(\"Push Negation failed! I am here!\")": #pylint: disable=line-too-long
        return ("Frontend Crash", [], outp)
      raise e
    
    error("Transitions file in ", transitionsF.name)
    args = [ INVGEN_PATH + invgenName, transitionsF.name]
    error("Invgen output in ", invgenOut.name)
    try:
      raw = check_output(args, stderr=STDOUT);
    except CalledProcessError,e:
      outp = e.output.split("\n");
      if outp[-2] == "! 'All direct(loop free) path to error are unsat'":
        return ("InvGen Crash", [], outp);
      elif outp[-2] == "! pred2coeff('Bad Predicate')":
        return ("InvGen Crash", [], outp);
      raise e;
Ejemplo n.º 7
0
            default=True, help='Print results as a csv table')
    p.add_argument('--time-limit', type=int, default=300, \
            help='Time limit for ICE')
    p.add_argument('--waitEnter', action="store_true", \
                   default=False, help='Wait for user to perss Enter before continuing (great for debug)')
    args = p.parse_args()
    if args.waitEnter:
        eval(input("Press Enter to continue..."))
    lvlSetName, lvls = loadBoogieLvlSet(args.lvlset)

    res = {}
    conf = {}

    for lvlName, lvl in lvls.items():
        boogieFile = lvl["path"][2]
        error("Running ", lvlName)

        res[lvlName] = runICE(boogieFile, args.time_limit)

        solved, loopHeaderLbl, loopInvs, rawOutput = res[lvlName]
        conf_status = "N/A"

        if (solved):
            error("z3 invs: ", len(loopInvs), loopInvs)
            try:
                t = Timer(args.time_limit, handler)
                t.start()
                #alarm(args.time_limit)
                # On lvl d-14 for example the invariants explode exponentially due to
                # inlining of lets. So add timeout. Seems to be the only level with
                # this problem
Ejemplo n.º 8
0
      "nusersFinished": 0,\
      "invs": set(),\
      "ninvs": 0,\
      "invariantsTried": set(),\
      "nInvariantsTried": 0,\
      "invariantsFound": set(),\
      "nInvariantsFound": 0,\
      "skipped": 0,\
      "totalTime": timedelta(),\
    } for lvlN in lvls }

for e in s.query(Event).all():
    typ, src, ename, time, p = e.type, e.src, e.experiment, e.time, e.payl()

    if ('lvlset' in p and p['lvlset'] != lvlsetName):
        error("Logs refer to levelset " + p['lvlset'] +
              " which is not loaded.")

    if ('lvlid' in p and p['lvlid'] not in lvls):
        error("Logs refer to level " + p['lvlid'] + \
              " which is not found in current lvlset.")

    if ('lvlid' in p):
        lvl = lvls[p['lvlid']]
        lvlS = lvlStats[p['lvlid']]
    else:
        lvl = None
        lvlS = None

    if (typ == "FoundInvariant"):
        lvlS["invariantsFound"].add((p['raw'], p['canonical']))
Ejemplo n.º 9
0
        help='Lvl-id in level set to try and verify"')
p.add_argument('invs', type=str, nargs="+", help="Invariants to try")
p.add_argument('--timeout', type=int, \
        help="Optional z3 timeout", default=None)

args = p.parse_args();

_, lvls = loadBoogieLvlSet(args.lvlset)
lvl = lvls[args.lvlid]
boogie_invs = set([])

for inv in args.invs:
  try:
    bInv = parseExprAst(inv);
    boogie_invs.add(bInv);
  except Exception:
    error("Failed parsing invariant " + inv);
    exit(-1);

((overfitted, overfitted_p2), (nonind, nonind_p2), sound, violations) =\
  tryAndVerifyLvl(lvl, boogie_invs, set(), args.timeout)

overfitted = set(overfitted).union(overfitted_p2)
nonind = set(nonind).union(nonind_p2)

print("Overfitted: ", overfitted)
print("Nonind: ", nonind)
print("Sound: ", sound)
print("Violations: ", violations)
print("Verified? ", len(violations) == 0)
Ejemplo n.º 10
0
                stmt = bbs[s.pc.bb][s.pc.next_stmt]
                if not isinstance(stmt, AstAssume):
                    return True

                v = eval_quick(stmt.expr, s.store)
                check(v, bool)
                return v

            feasible_states = filter(lambda x: lookahead_one_filter(bbs, x),
                                     states)
            return [choice(feasible_states)]

        filt_f = f
    else:
        error("Usage: unknown nond-mode: {}".format(args.nond_mode))

    rand_f = lambda state, Id: randint(-1000, 1000)

    starting_state = State(PC(bbEntry(bbs), 0), starting_store, RUNNING)
    (active, inactive) = trace_n(bbs, starting_state, args.steps, rand_f,
                                 filt_f)

    def pp_state(st):
        return "[{},{}]: ".format(st.pc.bb, st.pc.next_stmt) + \
               ",".join([k + "={}".format(v) for (k, v) in st.store.items()])

    def pp_trace(t):
        return "->\n".join(map(pp_state, t))

    print "Active({}):".format(len(active))
Ejemplo n.º 11
0
        print "Level,Invariants,TranslatedTo,Solved,Confirmed"

    for lvlName, lvl in lvls.iteritems():
        cppFile = lvl["path"][1]
        invgenCppFile = cppFile + ".invgen.preprocessed"

        if (not exists(invgenCppFile)):
            optionalManualModifiedFile = cppFile + ".invgen.manual.pretranslation"
            if (exists(optionalManualModifiedFile)):
                src = optionalManualModifiedFile
            else:
                src = cppFile

            convertCppFileForInvGen(src, invgenCppFile)

        error("Running ", lvlName)

        mainRoutine = "main" if lvlName != "i-cegar1" else "cegar1"
        res[lvlName] = runInvGen(invgenCppFile, mainRoutine)

        solved, loopInvs, rawOutput = res[lvlName]
        conf_status = "n/a"

        if (solved == True):
            error("z3 invs: ", len(loopInvs), loopInvs)
            boogieInvs = map(parseInvGenInvariant, loopInvs)
            bbs = lvl["program"]
            loop = lvl["loop"]
            try:
                ((overfitted, overfitted2), (nonind, nonind2), sound, violations) =\
                  tryAndVerifyLvl(lvl, set(boogieInvs), set(), args.time_limit, \