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); }
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); }
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); } }
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); } } }