Ejemplo n.º 1
0
        static Program RunDuality(string file)
        {
            Console.WriteLine("Running Duality on {0}", file);

            File.Delete("pm_corral_houd.bpl");
            File.Delete("duality_fp.bpl");

            var res =
                Util.run(Environment.CurrentDirectory, corralExe, string.Format("{0} /trackAllVars /runHoudini /useDuality /bopt:printFixedPoint:duality_fp.bpl /printHoudiniQuery:corral_houd.bpl /recursionBound:10000 /disableStaticAnalysis", file));

            if (!File.Exists("pm_corral_houd.bpl") || !File.Exists("duality_fp.bpl"))
            {
                Console.WriteLine("Proof not found");
                return(null);
            }

            var program = BoogieUtil.ReadAndOnlyResolve("pm_corral_houd.bpl");

            program = InjectDualityProof(program, "duality_fp.bpl");

            return(program);
        }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            con = new Context();

            string
                inFileName           = null,
                unrolledFileName     = null,
                tidRewrittenFileName = null,
                expandedFileName     = null,
                annotatedFileName    = null,
                splitFileName        = null,
                yieldedFileName      = null,
                instantiatedFileName = null,
                finalFileName        = null,
                mhpFileName          = null,
                hmifFileName         = null;

            dbg = false;

            inFileName = parseCommandLine(args);

            string[] parts = inFileName.Split('.');
            if (parts.Count() == 1)
            {
                unrolledFileName     = inFileName + "_unrolled";
                hmifFileName         = inFileName + "_hmif";
                expandedFileName     = inFileName + "_expanded";
                tidRewrittenFileName = inFileName + "_tidRewritten";
                annotatedFileName    = inFileName + "_annotated";
                splitFileName        = inFileName + "_split";
                yieldedFileName      = inFileName + "_yielded";
                finalFileName        = inFileName + "_final";
                mhpFileName          = inFileName + "_mhp";
                instantiatedFileName = inFileName + "_inst";
            }
            else
            {
                string name = parts[0];
                unrolledFileName     = name + "_unrolled";
                hmifFileName         = name + "_hmif";
                expandedFileName     = name + "_expanded";
                annotatedFileName    = name + "_annotated";
                splitFileName        = name + "_split";
                yieldedFileName      = name + "_yielded";
                finalFileName        = name + "_final";
                mhpFileName          = name + "_mhp";
                instantiatedFileName = name + "_inst";
                tidRewrittenFileName = name + "_tidRewritten";
                for (int i = 1; i < parts.Count(); ++i)
                {
                    unrolledFileName     += "." + parts[i];
                    hmifFileName         += "." + parts[i];
                    expandedFileName     += "." + parts[i];
                    annotatedFileName    += "." + parts[i];
                    splitFileName        += "." + parts[i];
                    yieldedFileName      += "." + parts[i];
                    finalFileName        += "." + parts[i];
                    tidRewrittenFileName += "." + parts[i];
                    mhpFileName          += "." + parts[i];
                    instantiatedFileName += "." + parts[i];
                }
            }

            var tmpFileName = "og__tmp.bpl";

            ExecutionEngine.printer = new ConsolePrinter();
            //CommanLineOptions will control how boogie parses the program and gives us the IR
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.Parse(new string[] { });
            CommandLineOptions.Clo.PrintInstrumented         = true;
            CommandLineOptions.Clo.StratifiedInliningVerbose = 2;
            CommandLineOptions.Clo.UseArrayTheory            = true;
            CommandLineOptions.Clo.TypeEncodingMethod        = CommandLineOptions.TypeEncoding.Monomorphic;

            Program program;

            program = BoogieUtil.ReadAndOnlyResolve(inFileName);

            // TODO: assert that no procedure can be called in both sync and async mode!


            // Find entrypoint and initialize con
            var entry = program.TopLevelDeclarations.OfType <Procedure>()
                        .Where(proc => QKeyValue.FindBoolAttribute(proc.Attributes, "entrypoint"))
                        .FirstOrDefault();

            if (entry == null)
            {
                Console.WriteLine("Warning: No entrypoint given");
                con.entryFunc = null;
            }
            else
            {
                con.entryFunc = entry.Name;
            }

            // Remove unreachable procedures
            BoogieUtil.pruneProcs(program, con.entryFunc);

            // Extract loops
            if (extractLoops)
            {
                program.ExtractLoops();
            }

            BoogieUtil.DoModSetAnalysis(program);

            if (pruneAsserts)
            {
                program = og.GuardAsserts(program);
            }

            if (injectYields)
            {
                program = og.InsertYields(program);
            }

            if (instantiateTemplates)
            {
                var inst = new TemplateInstantiator(program);
                inst.Instantiate(program);
                program = BoogieUtil.ReResolve(program, dbg ? instantiatedFileName : tmpFileName);
            }

            var sp   = new SplitThreads(con, dbg);
            var hmif = new HowManyInstanceFinder(con, dbg);

            var split = new Converter <Program, Program>(sp.split);
            var findHowManyInstances = new Converter <Program, Program>(hmif.Compute);

            if (entry != null && splitThreads)
            {
                if (dbg)
                {
                    Console.WriteLine("Splitting procedures on thread entry: {0}", splitFileName);
                }

                program = split(program);
                program = BoogieUtil.ReResolve(program, dbg ? hmifFileName : tmpFileName);

                program = findHowManyInstances(program);
                program = BoogieUtil.ReResolve(program, dbg ? splitFileName : tmpFileName);
            }

            // Get rid of corral_yield
            program = og.RemoveCorralYield(program, con.yieldProc);


            var yieldedProgram = new ProgTransformation.PersistentProgram(program);

            if (dbg)
            {
                Console.WriteLine("Instrumenting: {0}", annotatedFileName);
            }

            if (!noTid)
            {
                program = og.InstrumentTid(program);
            }

            program = og.InstrumentAtomicBlocks(program);

            if (instrumentPermissions)
            {
                program = og.InstrumentPermissions(program);
            }

            program = BoogieUtil.ReResolve(program, dbg ? annotatedFileName : tmpFileName);

            CommandLineOptions.Clo.ContractInfer     = true;
            CommandLineOptions.Clo.AbstractHoudini   = absDomain;
            CommandLineOptions.Clo.UseProverEvaluate = true;
            CommandLineOptions.Clo.ModelViewFile     = "z3model";
            Microsoft.Boogie.Houdini.AbstractDomainFactory.Initialize(program);

            // First, do sequential
            var answer = DoInference(program, InferenceMode.SEQUENTIAL, annotatedFileName, expandedFileName);

            program = BoogieUtil.ReadAndOnlyResolve(dbg ? annotatedFileName : tmpFileName);

            // prune "true" functions
            var progFuncs = new Dictionary <string, Function>();

            program.TopLevelDeclarations.OfType <Function>()
            .Iter(f => progFuncs.Add(f.Name, f));

            var truefuncs = new List <Function>();

            foreach (var f in answer)
            {
                if (f.Body is LiteralExpr && (f.Body as LiteralExpr).IsTrue)
                {
                    truefuncs.Add(f);
                    var actualf = progFuncs[f.Name];
                    actualf.Attributes = BoogieUtil.removeAttr("existential", actualf.Attributes);
                    actualf.Body       = Expr.True;
                }
            }
            Console.WriteLine("Sequential check pruned away {0} functions, {1} remain", truefuncs.Count, answer.Count() - truefuncs.Count);

            // now do concurrent
            answer = DoInference(program, InferenceMode.CONCURRENT, annotatedFileName, expandedFileName);
            answer = answer.Concat(truefuncs);

            var provedAsserts = new Dictionary <string, bool>();

            answer.Where(func => QKeyValue.FindBoolAttribute(func.Attributes, "assertGuard"))
            .Iter(func => {
                var le = func.Body as LiteralExpr;
                System.Diagnostics.Debug.Assert(le != null);
                provedAsserts.Add(func.Name, le.IsFalse);
            });

            // remove injected existential functions
            answer = answer.Where(func => !QKeyValue.FindBoolAttribute(func.Attributes, "chignore") &&
                                  !QKeyValue.FindBoolAttribute(func.Attributes, "assertGuard"));

            if (printAssignment)
            {
                using (var tt = new TokenTextWriter(Console.Out))
                    answer.ToList().Iter(func => func.Emit(tt, 0));
            }


            if (dbg)
            {
                Console.WriteLine("Injecting invariants back into the original program: {0}", finalFileName);
            }

            program = yieldedProgram.getProgram();

            // remove existential functions
            program.RemoveTopLevelDeclarations(decl => (decl is Function) && QKeyValue.FindBoolAttribute((decl as Function).Attributes, "existential"));
            program.AddTopLevelDeclarations(answer);

            program = og.PruneProvedAsserts(program, f => provedAsserts[f]);

            // Remove ensures and requires
            program = og.RemoveRequiresAndEnsures(program);
            // Remove tid func
            program = og.RemoveThreadIdFunc(program);
            using (Microsoft.Boogie.TokenTextWriter writer = new Microsoft.Boogie.TokenTextWriter(finalFileName))
                program.Emit(writer);
        }
Ejemplo n.º 3
0
        static void Main(string[] args)
        {
            Console.CancelKeyPress += Console_CancelKeyPress;

            if (args.Length < 1)
            {
                Console.WriteLine("Usage: FastAVN file.bpl");
                return;
            }

            if (args.Any(s => s == "/break"))
            {
                System.Diagnostics.Debugger.Launch();
            }

            if (args.Any(s => s == "/keepFiles"))
            {
                Driver.keepFiles = true;
            }

            args.Where(s => s.StartsWith("/aopt:"))
            .Iter(s => avnArgs += " /" + s.Substring("/aopt:".Length) + " ");

            args.Where(s => s.StartsWith("/hopt:"))
            .Iter(s => avHarnessInstrArgs += " /" + s.Substring("/hopt:".Length) + " ");

            if (args.Any(s => s == "/createEntrypointBplsOnly"))
            {
                Driver.createEntryPointBplsOnly = true;
            }
            if (args.Any(s => s == "/mergeEntrypointBugsOnly"))
            {
                Driver.mergeEntryPointBugsOnly = true;
            }

            // user definded verbose level
            args.Where(s => s.StartsWith("/verbose:"))
            .Iter(s => verbose = int.Parse(s.Substring("/verbose:".Length)));

            // depth k used by implementation pruning
            args.Where(s => s.StartsWith("/depth:"))
            .Iter(s => approximationDepth = int.Parse(s.Substring("/depth:".Length)));

            args.Where(s => s.StartsWith("/numThreads:"))
            .Iter(s => numThreads = int.Parse(s.Substring("/numThreads:".Length)));

            // Get config for remote execution
            args.Where(s => s.StartsWith("/config:"))
            .Iter(s => config = FastAvnConfig.DeSerialize(s.Substring("/config:".Length)));

            args.Where(s => s.StartsWith("/killAfter:"))
            .Iter(s => deadline = int.Parse(s.Substring("/killAfter:".Length)));

            // default args
            avnArgs += " /dumpResults:" + bugReportFileName + " ";
            avnArgs += " /EE:onlySlicAssumes+ /EE:ignoreAllAssumes- ";

            // Find AVN executable
            avnPath            = findExe("AngelicVerifierNull.exe");
            avHarnessInstrPath = findExe("AvHarnessInstrumentation.exe");

            psexecPath = findExe("psexec.exe");

            Debug.Assert(avnPath != null && avHarnessInstrPath != null);

            try
            {
                Stats.resume("fastavn");
                if (Driver.mergeEntryPointBugsOnly)
                {
                    // collate bugs
                    lock (fslock)
                    {
                        printingOutput = true;
                        if (Directory.Exists(bug_folder))
                        {
                            Utils.Print(string.Format("WARNING!! Removing {0} folder", bug_folder));
                            Directory.Delete(Path.Combine(Directory.GetCurrentDirectory(), bug_folder), true);
                        }
                        HashSet <string> epNames = new HashSet <string>(Directory.GetDirectories(@"."));
                        epNames = new HashSet <string>(epNames.Select(s => Path.GetFileName(s)));
                        printBugs(ref mergedBugs, epNames.Count);
                        mergeBugs(epNames);
                    }
                    return;
                }
                // Get input program
                Utils.Print(String.Format("----- Run FastAVN on {0} with k={1} ------",
                                          args[0], approximationDepth), Utils.PRINT_TAG.AV_OUTPUT);

                // initialize corral and boogie for fastAVN
                InitializeCorralandBoogie();

                // Run harness instrumentation
                var resultfile = Path.Combine(Directory.GetCurrentDirectory(), "hinst.bpl");
                var hinstOut   = RemoteExec.run(Directory.GetCurrentDirectory(), avHarnessInstrPath, string.Format("{0} \"{1}\" {2}", args[0], resultfile, avHarnessInstrArgs));

                hinstOut.Iter(s => Console.WriteLine("[hinst] {0}", s));

                if (!File.Exists(resultfile))
                {
                    throw new Exception("Error running harness instrumentation");
                }

                var prog = BoogieUtil.ReadAndOnlyResolve(resultfile);

                // Do a run on instrumented program, filter out entrypoints
                var entrypoints     = new HashSet <string>();
                var entrypoint_impl = prog.TopLevelDeclarations.OfType <Implementation>()
                                      .Where(impl => QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "entrypoint"))
                                      .FirstOrDefault();
                Debug.Assert(entrypoint_impl != null);

                // other entrypoints can never reach an assertion, don't run AVN on them
                foreach (Block b in entrypoint_impl.Blocks)
                {
                    b.Cmds.OfType <CallCmd>()
                    .Where(cc => QKeyValue.FindBoolAttribute(cc.Attributes, AvUtil.AvnAnnotations.AvhEntryPointAttr))
                    .Iter(cc => entrypoints.Add(cc.callee));
                }

                // do reachability analysis on procedures
                // prune deep (depth > K) implementations: treat as angelic
                sliceAndRunAVN(prog, approximationDepth, entrypoints);

                Stats.stop("fastavn");
                Stats.printStats();
            }
            catch (Exception e)
            {
                //stacktrace containts source locations, confuses regressions that looks for AV_OUTPUT
                Utils.Print(String.Format("FastAVN failed with: {0}", e.Message), Utils.PRINT_TAG.AV_OUTPUT);
                Utils.Print(String.Format("FastAVN failed with: {0}", e.Message + e.StackTrace), Utils.PRINT_TAG.AV_DEBUG);
            }
        }
Ejemplo n.º 4
0
            public void Run()
            {
                Implementation impl;
                var            rd = "";

                while (true)
                {
                    if (!impls.TryTake(out impl))
                    {
                        break;
                    }

                    while (!resources.TryTake(out rd))
                    {
                        Thread.Sleep(100);
                    }

                    sem.WaitOne();

                    var wd = Path.Combine(rd, impl.Name); // create new directory for each entrypoint

                    Directory.CreateDirectory(wd);        // create new directory for each entrypoint
                    RemoteExec.CleanDirectory(wd);
                    var     pruneFile = Path.Combine(wd, "pruneSlice.bpl");
                    Program newprogram;

                    // lock because Parsing a program is not thread-safe
                    lock (fslock)
                    {
                        BoogieUtil.PrintProgram(program, pruneFile);           // dump original program (so that each entrypoint has its own copy of program)
                        newprogram = BoogieUtil.ReadAndOnlyResolve(pruneFile); // entrypoint's copy of the program
                    }

                    // slice the program by entrypoints
                    Program shallowP = pruneDeepProcs(newprogram, ref edges, impl.Name, approximationDepth, implNames);
                    BoogieUtil.pruneProcs(shallowP,
                                          shallowP.TopLevelDeclarations.OfType <Procedure>()
                                          .Where(proc => BoogieUtil.checkAttrExists("entrypoint", proc.Attributes))
                                          .Select(proc => proc.Name)
                                          .FirstOrDefault());

                    File.Delete(pruneFile);
                    lock (fslock)
                    {
                        BoogieUtil.PrintProgram(shallowP, pruneFile); // dump sliced program
                    }

                    sem.Release();

                    if (Driver.createEntryPointBplsOnly)
                    {
                        Console.WriteLine("Skipping AVN run for {0} given /createEntrypointBplsOnly", impl.Name);
                        resources.Add(rd);
                        continue;
                    }
                    if (!remotedirs.Contains(rd))
                    {
                        Console.WriteLine("Running entrypoint {0} locally {{", impl.Name);

                        if (deadlineReached)
                        {
                            return;
                        }

                        // spawn the job -- local
                        var output = RemoteExec.run(wd, avnPath, string.Format("\"{0}\" {1}", pruneFile, avnArgs));

                        lock (fslock)
                        {
                            // delete temp files
                            if (!keepFiles)
                            {
                                var files = System.IO.Directory.GetFiles(wd, "*.bpl");
                                foreach (var f in files)
                                {
                                    System.IO.File.Delete(f);
                                }
                            }

                            using (StreamWriter sw = new StreamWriter(Path.Combine(wd, "stdout.txt")))
                                output.Iter(s => sw.WriteLine("{0}", s));
                        }

                        Console.WriteLine("Running entrypoint {0} locally }}", impl.Name);
                    }
                    else
                    {
                        // spawn the job -- remote
                        if (psexecPath == null)
                        {
                            throw new FileNotFoundException("Cannot find PSEXEC!");
                        }

                        // find the name of the machine from the remote folder name
                        var machine    = "";
                        var remoteroot = RemoteExec.GetRemoteFolder(rd, out machine);

                        Console.WriteLine("Running entrypoint {0} on {1} {{", impl.Name, machine);

                        // psexec machine -w remoteroot\impl remoteroot\fastavn\fastavn.exe remoteroot args
                        wd = Path.Combine(remoteroot, impl.Name);
                        var cmd = string.Format("{0} -w {1} {2} {3} {4}", machine, wd, Path.Combine(remoteroot, "fastavn", "AngelicVerifierNull.exe"),
                                                "pruneSlice.bpl", avnArgs);
                        //Console.WriteLine("PSEXEC Running: {0}", cmd);

                        if (deadlineReached)
                        {
                            return;
                        }

                        var output = RemoteExec.run(Directory.GetCurrentDirectory(), psexecPath, cmd);

                        lock (fslock)
                        {
                            // delete temp files
                            var td = Path.Combine(rd, impl.Name);
                            if (debug)
                            {
                                Console.WriteLine("Getting files in directory: {0}", td);
                            }
                            var files = System.IO.Directory.GetFiles(td, "*.bpl");
                            foreach (var f in files)
                            {
                                if (debug)
                                {
                                    Console.WriteLine("Deleting {0}", f);
                                }
                                System.IO.File.Delete(f);
                            }

                            // copy the results back
                            var ld = Path.Combine(Directory.GetCurrentDirectory(), impl.Name);
                            Directory.CreateDirectory(ld);
                            RemoteExec.CleanDirectory(ld);
                            RemoteExec.CopyFolder(rd, Directory.GetCurrentDirectory(), impl.Name, true);

                            using (StreamWriter sw = new StreamWriter(Path.Combine(ld, "stdout.txt")))
                                output.Iter(s => sw.WriteLine("{0}", s));
                        }

                        Console.WriteLine("Running entrypoint {0} on {1} }}", impl.Name, machine);
                    }

                    lock (fslock)
                    {
                        // collect and merge bugs
                        var bugs = collectBugs(Path.Combine(Directory.GetCurrentDirectory(), impl.Name, bugReportFileName));
                        bugs.Iter(b =>
                        {
                            if (!mergedBugs.ContainsKey(b))
                            {
                                mergedBugs[b] = 0;
                            }
                            mergedBugs[b] += 1;
                        });
                        Utils.Print(string.Format("Bugs found so far: {0}", mergedBugs.Count));

                        resources.Add(rd);
                    }
                }
            }