static void Main(string[] args) { if (args.Length < 2) { Console.WriteLine("usage: SmackInst.exe infile.bpl outfile.bpl [options]"); return; } if (args.Any(a => a == "/break")) { System.Diagnostics.Debugger.Launch(); } if (args.Any(a => a == "/initMem")) { initMem = true; } // initialize Boogie CommandLineOptions.Install(new CommandLineOptions()); CommandLineOptions.Clo.PrintInstrumented = true; // Read the input file var program = BoogieUtil.ReadAndResolve(args[0]); // Process it program = Process(program); // write the output BoogieUtil.PrintProgram(program, args[1]); }
public void Unify(string outfile) { // Gather all maps AllMaps = new HashSet <string>(); program.TopLevelDeclarations .OfType <GlobalVariable>() .Where(g => g.TypedIdent.Type.IsMap && (g.TypedIdent.Type as MapType).Result.IsInt) .Iter(g => AllMaps.Add(g.Name)); // Fix Cmds program.TopLevelDeclarations .OfType <Implementation>() .Iter(impl => impl.Blocks.Iter(block => block.Cmds .OfType <Cmd>().Iter(cmd => Visit(cmd)))); program.TopLevelDeclarations.OfType <Procedure>() .Iter(p => VisitEnsuresSeq(p.Ensures)); program.TopLevelDeclarations.OfType <Procedure>() .Iter(p => VisitRequiresSeq(p.Requires)); var impls = new HashSet <string>(); program.TopLevelDeclarations.OfType <Implementation>() .Iter(impl => impls.Add(impl.Name)); program.TopLevelDeclarations.OfType <Procedure>() .Where(p => impls.Contains(p.Name)) .Iter(p => p.Modifies = new List <IdentifierExpr>()); program.TopLevelDeclarations.OfType <Procedure>() .Iter(p => VisitIdentifierExprSeq(p.Modifies)); // Remove globals var newDecls = new List <Declaration>(); foreach (var decl in program.TopLevelDeclarations) { var glob = decl as GlobalVariable; if (glob == null || !AllMaps.Contains(glob.Name)) { newDecls.Add(decl); } } program.TopLevelDeclarations = newDecls; program.AddTopLevelDeclaration(U); // print program BoogieUtil.DoModSetAnalysis(program); BoogieUtil.PrintProgram(program, outfile); program = null; }
//TODO: collect some stats about the instrumentation, mb some debugging output?? private static void Main(string[] args) { if (args.Length < 3) { Console.WriteLine("usage: PropInst.exe propertyFile.avp boogieInputFile.bpl boogieOutputFile.bpl"); return; } if (args.Any(s => s == "/break")) { System.Diagnostics.Debugger.Launch(); } // initialize Boogie CommandLineOptions.Install(new CommandLineOptions()); CommandLineOptions.Clo.PrintInstrumented = true; // read the boogie program that is to be instrumented var boogieProgram = BoogieUtil.ReadAndResolve(args[1], false); // parse the property file var propLines = File.ReadLines(args[0]); string globalDeclarations; List <Rule> rules; CreateRulesFromProperty(propLines, out globalDeclarations, out rules); // GlobalDeclarations: add the global declarations from the property to the Boogie program Program dummyProg; Parser.Parse(globalDeclarations, "dummy.bpl", out dummyProg); boogieProgram.AddTopLevelDeclarations(dummyProg.TopLevelDeclarations); //resolve the program with the new declarations which may include funcs and procs with bodies boogieProgram.Resolve(); // CmdRule: find insertions sites (Commands), insert code there InstrumentCmdRule.Instrument(boogieProgram, rules.OfType <CmdRule>()); // InsertAtBeginningRule: find insertion sites (Procedures), insert code there InstrumentProcedureRule.Instrument(boogieProgram, rules.OfType <InsertAtBeginningRule>()); // make functions with {:mkUniqueFn} unique (new MkUniqueFnVisitor(boogieProgram)).Visit(boogieProgram); //augment the CorralExtraInit procedure (perform this after Matching/instrumentation) AugmentCorralExtraInit(boogieProgram); string outputFile = args[2]; BoogieUtil.PrintProgram(boogieProgram, outputFile); Stats.printStats(); }
public static void RunOnce(PersistentProgram inprog, bool printcontracts) { var program = inprog.getProgram(); program.Typecheck(); BoogieUtil.PrintProgram(program, "hi_query.bpl"); Console.WriteLine("Running HoudiniLite"); var assignment = CoreLib.HoudiniInlining.RunHoudini(program, true); Console.WriteLine("Inferred {0} contracts", assignment.Count); // Read the program again, add contracts program = inprog.getProgram(); program.Typecheck(); var contracts = CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, assignment); BoogieUtil.PrintProgram(program, "si_query.bpl"); // Run SI var err = new List <BoogieErrorTrace>(); var rstatus = BoogieVerify.Verify(program, out err, true); Console.WriteLine("SI Return status: {0}", rstatus); if (err == null || err.Count == 0) { Console.WriteLine("program verified"); } else { foreach (var trace in err.OfType <BoogieAssertErrorTrace>()) { Console.WriteLine("{0} did not verify", trace.impl.Name); //if (!config.noTrace) trace.cex.Print(0, Console.Out); } } Console.WriteLine(string.Format("Procedures Inlined: {0}", BoogieVerify.CallTreeSize)); Console.WriteLine(string.Format("Boogie verification time: {0} s", BoogieVerify.verificationTime.TotalSeconds.ToString("F2"))); if (printcontracts) { foreach (var tup in contracts) { Console.WriteLine("{0}: {1}", tup.Key, tup.Value); } } }
BoogieVerify.ReturnStatus PruneAndRun(PersistentProgram inp, HashSet <string> candidates, out HashSet <string> assignment, ref int inlined) { IterCnt++; var program = inp.getProgram(); program.Typecheck(); // Remove non-candidates CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, candidates, true); program.RemoveTopLevelDeclarations(decl => (decl is Constant) && QKeyValue.FindBoolAttribute(decl.Attributes, "existential") && !candidates.Contains((decl as Constant).Name)); BoogieUtil.PrintProgram(program, "hi_query" + IterCnt + ".bpl"); // Run Houdini assignment = CoreLib.HoudiniInlining.RunHoudini(program, true); Console.WriteLine(" >> Contracts: {0}", assignment.Count); // Read the program again, add contracts program = inp.getProgram(); program.Typecheck(); CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, assignment); BoogieUtil.PrintProgram(program, "si_query" + IterCnt + ".bpl"); // Run SI var err = new List <BoogieErrorTrace>(); // Set bound BoogieVerify.options.maxInlinedBound = 0; if (inlined != 0) { BoogieVerify.options.maxInlinedBound = PerfMetric(inlined); } var rstatus = BoogieVerify.Verify(program, out err, true); Console.WriteLine(string.Format(" >> Procedures Inlined: {0}", BoogieVerify.CallTreeSize)); //Console.WriteLine(string.Format("Boogie verification time: {0} s", BoogieVerify.verificationTime.TotalSeconds.ToString("F2"))); inlined = BoogieVerify.CallTreeSize + 1; BoogieVerify.options.CallTree = new HashSet <string>(); BoogieVerify.CallTreeSize = 0; BoogieVerify.verificationTime = TimeSpan.Zero; return(rstatus); }
// Check that assert and return only appear together private static void RemoveAsserts(Program program) { var mains = program.TopLevelDeclarations .OfType <Implementation>() .Where(impl => QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint")); foreach (var main in mains) { foreach (var blk in main.Blocks) { var isReturn = (blk.TransferCmd is ReturnCmd); var assertPos = -2; for (int i = 0; i < blk.Cmds.Count; i++) { if (BoogieUtil.isAssertTrue(blk.Cmds[i])) { continue; } if (blk.Cmds[i] is AssertCmd) { assertPos = i; break; } } if (!isReturn && assertPos != -2) { BoogieUtil.PrintProgram(program, "error.bpl"); throw new InternalError("assert is not followed by return"); } if (isReturn) { if (assertPos != blk.Cmds.Count - 1) { //throw new InternalError("return is not preceeded by an assert"); blk.Cmds.Add(new AssumeCmd(Token.NoToken, Expr.False)); } else { var assertcmd = blk.Cmds[assertPos] as AssertCmd; blk.Cmds[assertPos] = new AssumeCmd(Token.NoToken, Expr.Not(assertcmd.Expr), new QKeyValue(Token.NoToken, "OldAssert", new List <object>(), null)); } } } } }
// Return a new copy of the program public override Program getProgram() { var startTime = DateTime.Now; FixedDuplicator dup = new FixedDuplicator(); Program ret = dup.VisitProgram(program); if (ret.Resolve() != 0 || ret.Typecheck() != 0) { BoogieUtil.PrintProgram(ret, "error.bpl"); throw new InternalError("Illegal program given to PersistentProgram"); } persistenceCost += (DateTime.Now - startTime); return(ret); }
static void doHwswLevelMatch(string infile, string outfile) { var program = BoogieUtil.ParseProgram(infile); foreach (var decl in program.TopLevelDeclarations) { var impl = decl as Implementation; if (impl == null) { continue; } doHwswLevelMatch(impl); } BoogieUtil.PrintProgram(program, outfile); }
static int Split(Program program, string filename) { var cnt = 1; foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()) { if (impl.Proc.Ensures.Any(ens => !ens.Free)) { var p = SplitOnProcedure(program, impl.Name); MarkEntryPoint(p, impl.Name); BoogieUtil.PrintProgram(p, filename.Replace(".bpl", string.Format("_split_{0}.bpl", cnt++))); } } return(cnt); }
static void Main(string[] args) { if (args.Length != 2) { Console.WriteLine("BctMemInst.exe input.bpl output.bpl [args]"); return; } CommandLineOptions.Install(new CommandLineOptions()); CommandLineOptions.Clo.PrintInstrumented = true; CommandLineOptions.Clo.DoModSetAnalysis = true; var input = BoogieUtil.ReadAndResolve(args[0]); var output = Process(input); if (output != null) { BoogieUtil.PrintProgram(output, args[1]); } }
//TODO: collect some stats about the instrumentation, mb some debugging output?? private static void Main(string[] args) { if (args.Length < 3) { Console.WriteLine("usage: PropInst.exe propertyFile.avp boogieInputFile.bpl boogieOutputFile.bpl"); return; } // initialize Boogie CommandLineOptions.Install(new CommandLineOptions()); CommandLineOptions.Clo.PrintInstrumented = true; // read the boogie program that is to be instrumented var boogieProgram = BoogieUtil.ReadAndResolve(args[1], false); // parse the property file var propLines = File.ReadLines(args[0]); string globalDeclarations; List <Rule> rules; CreateRulesFromProperty(propLines, out globalDeclarations, out rules); // GlobalDeclarations: add the global declarations from the property to the Boogie program Program dummyProg; Parser.Parse(globalDeclarations, "dummy.bpl", out dummyProg); boogieProgram.AddTopLevelDeclarations(dummyProg.TopLevelDeclarations); // CmdRule: find insertions sites (Commands), insert code there InstrumentCmdRule.Instrument(boogieProgram, rules.OfType <CmdRule>()); // InsertAtBeginningRule: find insertion sites (Procedures), insert code there InstrumentProcedureRule.Instrument(boogieProgram, rules.OfType <InsertAtBeginningRule>()); string outputFile = args[2]; BoogieUtil.PrintProgram(boogieProgram, outputFile); Stats.printStats(); }
public Program run(Program node) { globalsRead = new HashSet <string>(); // Typecheck -- needed for variable abstraction if (node.Typecheck() != 0) { BoogieUtil.PrintProgram(node, "error.bpl"); throw new InternalError("Type errors"); } // Go through all procedures and implementations (slice locals) var TopLevelDeclarations = node.TopLevelDeclarations.ToList(); for (int i = 0; i < TopLevelDeclarations.Count; i++) { if (TopLevelDeclarations[i] is Implementation) { TopLevelDeclarations[i] = processImplementation(TopLevelDeclarations[i] as Implementation); } else if (TopLevelDeclarations[i] is Procedure) { processProcedure(TopLevelDeclarations[i] as Procedure); } } node.TopLevelDeclarations = TopLevelDeclarations; if (onlyLocals) { return(node); } sliceGlobals = new VariableSlicing(VarSet.ToVarSet(globalsRead, node), gtinfo); node = sliceGlobals.VisitProgram(node); BoogieUtil.DoModSetAnalysis(node); return(node); }
static void MarkAllAssumes(Program program, string filename) { program = SplitOnProcedure(program, ""); BoogieUtil.PrintProgram(program, filename.Replace(".bpl", "_split_0.bpl")); }
static void Main(string[] args) { System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.Batch; if (args.Length < 2 || !args[0].EndsWith(".bpl") || !args[1].EndsWith(".bpl")) { Console.WriteLine("Usage: AvHarnessInstrumentation infile.bpl outfile.bpl [options]"); return; } SetOptions(args); // Initialize Boogie CommandLineOptions.Install(new CommandLineOptions()); CommandLineOptions.Clo.PrintInstrumented = true; BoogieUtil.InitializeBoogie(""); ProgTransformation.PersistentProgramIO.useDuplicator = true; var sw = new Stopwatch(); sw.Start(); if (Options.killAfter > 0) { var timer = new System.Timers.Timer(Options.killAfter * 1000); timer.Elapsed += (sender, e) => HandleTimer(sw); timer.Start(); } try { // Get the program, install the harness and do basic instrumentation var inprog = GetProgram(args[0]); Utils.Print(string.Format("#Procs : {0}", inprog.TopLevelDeclarations.OfType <Implementation>().Count()), Utils.PRINT_TAG.AV_STATS); Utils.Print(string.Format("#EntryPoints : {0}", harnessInstrumentation.entrypoints.Count), Utils.PRINT_TAG.AV_STATS); Utils.Print(string.Format("#AssertsBeforeAA : {0}", AssertCountVisitor.Count(inprog)), Utils.PRINT_TAG.AV_STATS); if (Options.delayAA) { PruneRedundantEntryPoints(inprog); BoogieUtil.PrintProgram(inprog, args[1]); } else { var program = new PersistentProgram(inprog, AvnAnnotations.CORRAL_MAIN_PROC, 0); // Run alias analysis Stats.resume("alias.analysis"); Console.WriteLine("Running alias analysis"); program = RunAliasAnalysis(program); Stats.stop("alias.analysis"); var assertCnt = AssertCountVisitor.Count(program.getProgram()); Utils.Print(string.Format("#AssertsAfterAA : {0}", assertCnt), Utils.PRINT_TAG.AV_STATS); // run Houdini pass if (Options.HoudiniPass) { Utils.Print("Running Houdini Pass"); program = RunHoudiniPass(program); assertCnt = AssertCountVisitor.Count(program.getProgram()); Utils.Print(string.Format("#Asserts : {0}", assertCnt), Utils.PRINT_TAG.AV_STATS); } if (assertCnt == 0) { // program has been proved correct // Write a trivial program System.IO.File.WriteAllLines(args[1], new string[] { "procedure {:entrypoint} {:NoVerificationNecessary} dummy() { }" }); } else { program.writeToFile(args[1]); } } } catch (Exception e) { //stacktrace containts source locations, confuses regressions that looks for AV_OUTPUT Utils.Print(String.Format("AngelicVerifier failed with: {0}", e.Message), Utils.PRINT_TAG.AV_OUTPUT); Utils.Print(String.Format("AngelicVerifier failed with: {0}", e.Message + e.StackTrace), Utils.PRINT_TAG.AV_DEBUG); } finally { Stats.printStats(); Utils.Print(string.Format("TotalTime(ms) : {0}", sw.ElapsedMilliseconds), Utils.PRINT_TAG.AV_STATS); } }
//TODO: collect some stats about the instrumentation, mb some debugging output?? private static void Main(string[] args) { if (args.Length < 3) { Console.WriteLine("usage: PropInst.exe propertyFile.avp boogieInputFile.bpl boogieOutputFile.bpl [options]"); Console.WriteLine("\t /pruneMethodsWithFilePathPrefix:<absolutePath> Prune implementations whose path has this prefix"); Console.WriteLine("\t /removeAssertsIfNoCallWithPrefix:<prefixString> Cleanup asserts if no methods prefixed with <prefixString> (e.g. ProbeFor) are present in the module"); return; } if (args.Any(s => s == "/break")) { System.Diagnostics.Debugger.Launch(); } var pruneFilePaths = new HashSet <string>(); args .Where(s => s.StartsWith("/pruneMethodsWithFilePathPrefix:")) .Iter(s => pruneFilePaths.Add(s.Substring("/pruneMethodsWithFilePathPrefix:".Length))); string cleanupPrefixString = null; var removeAssertConditions = args.Where(x => x.StartsWith("/removeAssertsIfNoCallWithPrefix:")); if (removeAssertConditions.Count() == 1) { cleanupPrefixString = removeAssertConditions.First().Substring("/removeAssertsIfNoCallWithPrefix:".Length); } else if (removeAssertConditions.Count() > 1) { Console.WriteLine("Expecting exactly one \"/removeAssertsIfNoCallWithPrefix:\" flag"); return; } // initialize Boogie CommandLineOptions.Install(new CommandLineOptions()); CommandLineOptions.Clo.PrintInstrumented = true; // read the boogie program that is to be instrumented var boogieProgram = BoogieUtil.ReadAndResolve(args[1], false); // parse the property file var propLines = File.ReadLines(args[0]); string globalDeclarations; List <Rule> rules; CreateRulesFromProperty(propLines, out globalDeclarations, out rules); // GlobalDeclarations: add the global declarations from the property to the Boogie program Program dummyProg; Parser.Parse(globalDeclarations, "dummy.bpl", out dummyProg); boogieProgram.AddTopLevelDeclarations(dummyProg.TopLevelDeclarations); //resolve the program with the new declarations which may include funcs and procs with bodies boogieProgram.Resolve(); // CmdRule: find insertions sites (Commands), insert code there InstrumentCmdRule.Instrument(boogieProgram, rules.OfType <CmdRule>()); // InsertAtBeginningRule: find insertion sites (Procedures), insert code there InstrumentProcedureRule.Instrument(boogieProgram, rules.OfType <InsertAtBeginningRule>()); // make functions with {:mkUniqueFn} unique (new MkUniqueFnVisitor(boogieProgram)).Visit(boogieProgram); //augment the CorralExtraInit procedure (perform this after Matching/instrumentation) AugmentCorralExtraInit(boogieProgram); // prune methods that match PruneFilePaths if (pruneFilePaths.Count() > 0) { PruneMethodsWithPaths(boogieProgram, pruneFilePaths); } // cleanup asserts if no method with prefix is present if (cleanupPrefixString != null) { PerformCleanupIfNoCallWithPrefix(boogieProgram, cleanupPrefixString); } string outputFile = args[2]; BoogieUtil.PrintProgram(boogieProgram, outputFile); Stats.printStats(); }
static void Main(string[] args) { // Initialize CommandLineOptions.Install(new CommandLineOptions()); CommandLineOptions.Clo.PrintInstrumented = true; // Find necessary files if (!LocateFiles()) { return; } var files = new HashSet <string>(); var pminargs = ""; foreach (var arg in args) { if (arg == "/break") { System.Diagnostics.Debugger.Launch(); continue; } if (arg.StartsWith("/")) { pminargs += arg + " "; continue; } // Fetch file names var fname = System.IO.Path.GetFileName(arg); var dirname = System.IO.Path.GetDirectoryName(arg); if (dirname == "") { dirname = "."; } files.UnionWith(System.IO.Directory.GetFiles(dirname, fname)); } // create proofbench directory if (!Directory.Exists(proofbench)) { Directory.CreateDirectory(proofbench); } else { Util.CleanDirectory(proofbench); } // Run duality, get proofs var cnt = 0; foreach (var file in files) { var proof = RunDuality(file); if (proof == null) { continue; } BoogieUtil.PrintProgram(proof, Path.Combine(proofbench, string.Format("pf{0}.bpl", cnt++))); } Console.WriteLine("Obtained {0} proofs", cnt); Console.WriteLine("Running Proof Minimization"); var res = Util.run(Environment.CurrentDirectory, proofMinExe, string.Format("{0} {1} /perf", Path.Combine(proofbench, "*.bpl"), pminargs)); File.WriteAllLines("proofmin_out.txt", res); var templates = ParseOutput(res); Console.WriteLine("Inferred annotations: "); templates.Iter(t => Console.WriteLine(" {0}", t)); }
public static ReturnStatus Verify(Program program, bool needErrorTraces, out List <BoogieErrorTrace> allErrors, out List <string> timedOut, bool isCBA = false) { ReturnStatus ret = ReturnStatus.OK; allErrors = new List <BoogieErrorTrace>(); timedOut = new List <string>(); Debug.Assert(program != null); // Make a copy of the input program var duper = new FixedDuplicator(true); var origProg = new Dictionary <string, Implementation>(); if (needErrorTraces) { foreach (var decl in program.TopLevelDeclarations) { if (decl is Implementation) { var origImpl = duper.VisitImplementation(decl as Implementation); origProg.Add(origImpl.Name, origImpl); } } } if (removeAsserts) { RemoveAsserts(program); } // Set options options.Set(); // save RB var rb = CommandLineOptions.Clo.RecursionBound; if (BoogieVerify.irreducibleLoopUnroll >= 0) { CommandLineOptions.Clo.RecursionBound = BoogieVerify.irreducibleLoopUnroll; } // Do loop extraction var extractionInfo = program.ExtractLoops(); // restore RB CommandLineOptions.Clo.RecursionBound = rb; // set bounds if (options.extraRecBound != null) { options.extraRecBound.Iter(tup => { var impl = BoogieUtil.findProcedureImpl(program.TopLevelDeclarations, tup.Key); if (impl != null) { impl.AddAttribute(BoogieVerify.ExtraRecBoundAttr, Expr.Literal(tup.Value)); } }); } #region Save program to disk if (shuffleProgram) { BoogieUtil.PrintProgram(program, "last_query.bpl"); program = BoogieUtil.ReadAndResolve("last_query.bpl"); } if (options.printProg) { Debug.Assert(options.progFileName != null, "Invalid options"); BoogieUtil.PrintProgram(program, options.progFileName); } #endregion var origBlocks = new Dictionary <string, Tuple <Block, Implementation> >(); // ---------- Infer invariants -------------------------------------------------------- // Abstract interpretation -> Always use (at least) intervals, if not specified otherwise (e.g. with the "/noinfer" switch) //Microsoft.Boogie.AbstractInterpretation.AbstractInterpretation.RunAbstractInterpretation(program); //// ---------- Verify ---------------------------------------------------------------- var mains = new List <Implementation>( program.TopLevelDeclarations .OfType <Implementation>() .Where(impl => QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint"))); VC.VCGen vcgen = null; try { Debug.Assert(CommandLineOptions.Clo.StratifiedInlining > 0); if (options.newStratifiedInlining) { if (options.newStratifiedInliningAlgo.ToLower() == "duality") { Microsoft.Boogie.SMTLib.Factory.UseInterpolation = true; } vcgen = new CoreLib.StratifiedInlining(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, null); } else // vcgen = new VC.StratifiedVCGen(options.CallTree != null, options.CallTree, options.procsToSkip, options.extraRecBound, program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, new List<Checker>()); if (!useDuality || !isCBA || !needErrorTraces || options.StratifiedInlining > 1 || mains.Count > 1) { vcgen = new VC.StratifiedVCGen(options.CallTree != null, options.CallTree, program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, new List <Checker>()); } else { CommandLineOptions.Clo.FixedPointMode = CommandLineOptions.FixedPointInferenceMode.Corral; CommandLineOptions.Clo.FixedPointEngine = "duality"; vcgen = new Microsoft.Boogie.FixedpointVC(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, new List <Checker>(), options.extraRecBound); } } catch (ProverException e) { Log.WriteLine(Log.Error, "ProverException: {0}", e.Message); return(ReturnStatus.OK); } if (!mains.Any()) { throw new InternalError("No entrypoint found"); } if (mains.Count > 1) { Console.WriteLine("Verifying {0} impls", mains.Count); } foreach (var impl in mains) { if (PrintImplsBeingVerified) { Log.WriteLine(Log.Verbose, "Verifying implementation " + impl.Name); } List <Counterexample> errors; VC.VCGen.Outcome outcome; try { var start = DateTime.Now; outcome = vcgen.VerifyImplementation(impl, out errors); var end = DateTime.Now; TimeSpan elapsed = end - start; Log.WriteLine(Log.Debug, string.Format(" [{0} s] ", elapsed.TotalSeconds)); verificationTime += elapsed; if (recordTempTime) { tempTime += elapsed; } } catch (VC.VCGenException e) { throw new InternalError("VCGenException: " + e.Message); //errors = null; //outcome = VC.VCGen.Outcome.Inconclusive; } catch (UnexpectedProverOutputException upo) { throw new InternalError("Unexpected prover output: " + upo.Message); //errors = null; //outcome = VC.VCGen.Outcome.Inconclusive; } switch (outcome) { case VC.VCGen.Outcome.Correct: break; case VC.VCGen.Outcome.Errors: break; case VC.VCGen.Outcome.ReachedBound: ret = ReturnStatus.ReachedBound; break; case VC.VCGen.Outcome.Inconclusive: throw new InternalError("z3 says inconclusive"); case VC.VCGen.Outcome.OutOfMemory: // wipe out any counterexamples timedOut.Add(impl.Name); errors = new List <Counterexample>(); break; case VC.VCGen.Outcome.OutOfResource: case VC.VCGen.Outcome.TimedOut: // wipe out any counterexamples timedOut.Add(impl.Name); errors = new List <Counterexample>(); break; default: throw new InternalError("z3 unknown response"); } Log.WriteLine(Log.Debug, outcome.ToString()); Log.WriteLine(Log.Debug, (errors == null ? 0 : errors.Count) + " counterexamples."); if (errors != null) { ret = ReturnStatus.NOK; } // Print model if (errors != null && errors.Count > 0 && errors[0].Model != null && CommandLineOptions.Clo.ModelViewFile != null) { var model = errors[0].Model; var cnt = 0; model.States.Iter(st => { if (st.Name.StartsWith("corral")) { st.ChangeName(st.Name + "_" + cnt.ToString()); cnt++; } }); using (var wr = new StreamWriter(CommandLineOptions.Clo.ModelViewFile, false)) { model.Write(wr); } } if (errors != null && needErrorTraces) { for (int i = 0; i < errors.Count; i++) { //errors[i].Print(1, Console.Out); // Map the trace across loop extraction if (vcgen is VC.VCGen) { errors[i] = (vcgen as VC.VCGen).extractLoopTrace(errors[i], impl.Name, program, extractionInfo); } if (errors[i] is AssertCounterexample) { // Special treatment for assert counterexamples for CBA: Reconstruct // trace in the input program. ReconstructImperativeTrace(errors[i], impl.Name, origProg); allErrors.Add(new BoogieAssertErrorTrace(errors[i] as AssertCounterexample, origProg[impl.Name], program)); } else { allErrors.Add(new BoogieErrorTrace(errors[i], origProg[impl.Name], program)); } } } } //PutBackAsserts(program); if (vcgen is StratifiedVCGen) { CallTreeSize = (vcgen as StratifiedVCGen).numInlined; vcSize = (vcgen as StratifiedVCGen).vcsize; if (options.CallTree != null) { options.CallTree = VC.StratifiedVCGen.callTree; VC.StratifiedVCGen.callTree = null; } } else if (vcgen is CoreLib.StratifiedInlining) { procsHitRecBound = (vcgen as CoreLib.StratifiedInlining).procsHitRecBound; CallTreeSize = (vcgen as CoreLib.StratifiedInlining).stats.numInlined; vcSize = (vcgen as CoreLib.StratifiedInlining).stats.vcSize; if (options.CallTree != null) { options.CallTree = (vcgen as CoreLib.StratifiedInlining).GetCallTree(); } } else { CallTreeSize = 0; } vcgen.Close(); CommandLineOptions.Clo.TheProverFactory.Close(); return(ret); }
// Assumptions: // - Program has no recursion public static HashSet <string> FindLeastToVerify(Program program, HashSet <string> boolVars) { Debug.Assert(program != null); RemoveAsserts(program); if (options.printProg) { BoogieUtil.PrintProgram(program, options.progFileName); } //// ---------- Verify ---------------------------------------------------------------- Debug.Assert(CommandLineOptions.Clo.StratifiedInlining > 0); VC.StratifiedVCGenBase vcgen = null; try { if (options.newStratifiedInlining) { vcgen = new CoreLib.StratifiedInlining(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, null); } else { vcgen = new VC.StratifiedVCGen(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, new List <Checker>()); } } catch (ProverException) { Log.WriteLine(Log.Error, "ProverException: {0}"); return(new HashSet <string>()); } var mains = program.TopLevelDeclarations .OfType <Implementation>() .Where(impl => QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint")); if (mains.Count() != 1) { throw new InternalError("Wrong number of entrypoints for FindLeastToverify"); } var main = mains.First(); VC.VCGen.Outcome outcome; //HashSet<string> minVars = new HashSet<string>(); try { var start = DateTime.Now; outcome = vcgen.FindLeastToVerify(main, ref boolVars); var end = DateTime.Now; TimeSpan elapsed = end - start; Log.WriteLine(Log.Debug, string.Format(" [{0} s] ", elapsed.TotalSeconds)); verificationTime += elapsed; if (recordTempTime) { tempTime += elapsed; } } catch (VC.VCGenException e) { throw new InternalError("VCGenException: " + e.Message); //errors = null; //outcome = VC.VCGen.Outcome.Inconclusive; } catch (UnexpectedProverOutputException upo) { throw new InternalError("Unexpected prover output: " + upo.Message); //errors = null; //outcome = VC.VCGen.Outcome.Inconclusive; } switch (outcome) { case VC.VCGen.Outcome.Correct: break; case VC.VCGen.Outcome.Errors: Debug.Assert(false); break; case VC.VCGen.Outcome.ReachedBound: Debug.Assert(false); break; case VC.VCGen.Outcome.Inconclusive: throw new InternalError("z3 says inconclusive"); case VC.VCGen.Outcome.OutOfMemory: throw new InternalError("z3 out of memory"); case VC.VCGen.Outcome.OutOfResource: case VC.VCGen.Outcome.TimedOut: throw new InternalError("z3 timed out"); default: throw new InternalError("z3 unknown response"); } Debug.Assert(outcome == VC.VCGen.Outcome.Correct); vcgen.Close(); CommandLineOptions.Clo.TheProverFactory.Close(); return(boolVars); }
// Write the program to a file public override void writeToFile(string fname) { BoogieUtil.PrintProgram(program, fname); }
public override CBAProgram runCBAPass(CBAProgram p) { if (p.mode == ConcurrencyMode.FixedContext) { InstrumentationConfig.addRaiseException = false; } // Step1: Gather program information pinfo = new ProgramInfo(p.mainProcName, p, LanguageSemantics.assertNotReachableName()); TidArithmetic.reset(); if (pinfo.threadIdType.IsBv) { TidArithmetic.useIntArithmetic = false; p.AddTopLevelDeclaration(TidArithmetic.getBvAdd()); p.AddTopLevelDeclaration(TidArithmetic.getBvGt()); } else { TidArithmetic.useIntArithmetic = true; } // Step2: Set up a variable manager vmgr = new VariableManager(pinfo); // Step3: Set up the instrumentation policy // The globals not to instrument are: // -- ones not modified by any procedure // -- ones not shared // -- ones to treat as thread-local HashSet <string> globalsToInstrument = new HashSet <string>(); foreach (var g in pinfo.declaredGlobals) { string name = g.Key; if (!pinfo.modifiedGlobals.ContainsKey(name)) { continue; } if (!LanguageSemantics.isShared(name)) { continue; } if (pinfo.threadLocalGlobals.ContainsKey(name)) { continue; } globalsToInstrument.Add(name); } var rprocs = findRecursiveProcs(p); //foreach (var be in rprocs) Console.WriteLine("{0} -> {1}", be.Item1, be.Item2); policy = new InstrumentationPolicy(p.contextBound, globalsToInstrument, pinfo.procsWithImplementation, pinfo.asyncProcs, rprocs, p.mode); //policy.print(Log.getWriter(Log.Debug)); // Step4: Split program declarations based on the instrumentation policy // skipping this step (not needed for basic CBA reduction) // Step5: Carry out the K-split instrumentation inst = new Instrumenter(policy, vmgr, pinfo, tinfo_instrument); List <Declaration> newDecls = inst.instrument(p.TopLevelDeclarations.ToList()); foreach (var trp in inst.blocksWithFixedK) { blockExecutionContextMap.Add(trp.fst + "::" + trp.snd, trp.trd); } // Step6: Instrument main with initialization and the Checker Implementation mainProcImpl = BoogieUtil.findProcedureImpl(newDecls, p.mainProcName); inst.instrumentGivenMainImpl(mainProcImpl); // Step7: Instrument Async calls bool instrumentedAsync = false; InstrumentAsyncCalls ainst = new InstrumentAsyncCalls(vmgr, pinfo, tinfo_async); foreach (var decl in newDecls) { if (decl is Implementation) { ainst.VisitImplementation(decl as Implementation); instrumentedAsync = instrumentedAsync || ainst.hasAsync; } } if (!instrumentedAsync) { Log.WriteLine(Log.Debug, "Warning: Did not find any async call"); } // Step8: Set entrypoint mainProcImpl.AddAttribute("entrypoint"); // Step9: Add new variable declarations newDecls.AddRange(vmgr.getNewDeclarations(policy.executionContextBound)); newDecls.AddRange(BoogieAstFactory.newDecls); BoogieAstFactory.newDecls.Clear(); // Thats it. Program ret = new Program(); ret.TopLevelDeclarations = newDecls; if (InstrumentationConfig.printInstrumented) { // Re-resolve ret ProgTransformation.PersistentProgram tprog = new ProgTransformation.PersistentProgram(ret); var instrumented = tprog.getProgram(); // Re-do the modsets -- make them as concise as possible. BoogieUtil.DoModSetAnalysis(instrumented); // Temporary fix for Boogie's bug while inlining calls // that have don't care expressions. RewriteCallDontCares rdc = new RewriteCallDontCares(); rdc.VisitProgram(instrumented); BoogieUtil.PrintProgram(instrumented, InstrumentationConfig.instrumentedFile); throw new NormalExit("Printed " + InstrumentationConfig.instrumentedFile); } // Resolve the program (Do not typecheck because that does inlining). //BoogieUtil.PrintProgram(ret, "instrumented.bpl"); //ret = BoogieUtil.ReadAndOnlyResolve("instrumented.bpl"); if (p.mode == ConcurrencyMode.FixedContext) { InstrumentationConfig.addRaiseException = true; } p = new CBAProgram(ret, p.mainProcName, p.contextBound); return(p); }
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); } } }
static void Main(string[] args) { if (args.Length < 2) { Console.WriteLine("usage: SmackInst.exe infile.bpl outfile.bpl [options]"); return; } if (args.Any(a => a == "/break")) { System.Diagnostics.Debugger.Launch(); } if (args.Any(a => a == "/initMem")) { initMem = true; } if (args.Any(a => a == "/replaceRoot")) { replaceRoot = true; } args.Where(a => a.StartsWith("/oldRoot:")) .Iter(a => oldRoot = a.Substring("/oldRoot:".Length)); args.Where(a => a.StartsWith("/newRoot:")) .Iter(a => newRoot = a.Substring("/newRoot:".Length)); if (args.Any(a => a == "/count")) { count = true; } if (args.Any(a => a == "/onlyCount")) { onlyCount = true; } if (args.Any(a => a == "/checkNULL")) { checkNULL = true; } if (args.Any(a => a == "/checkUAF")) { checkUAF = true; } if (args.Any(a => a == "/printCallGraph")) { printCallGraph = true; } if (args.Any(a => a == "/detectDeadCode")) { detectDeadCode = true; } if (args.Any(a => a == "/checkMemorySafety")) { checkMemSafety = true; } if (args.Any(a => a == "/visualizeHeap")) { visualizeHeap = true; } // initialize Boogie CommandLineOptions.Install(new CommandLineOptions()); CommandLineOptions.Clo.PrintInstrumented = true; CommandLineOptions.Clo.DoModSetAnalysis = true; // Read the input file var program = BoogieUtil.ReadAndResolve(args[0], false); // SMACK does not add globals to modify clauses //BoogieUtil.DoModSetAnalysis(program); if (checkMemSafety) { Procedure checkProc = program.TopLevelDeclarations.OfType <Procedure>().Where(x => x.Name == "__SMACK_check_memory_safety").FirstOrDefault(); foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()) { if (impl.Name == "__SMACK_check_memory_safety") { continue; } if (impl.Name.StartsWith("__SMACK_static_init")) { continue; } foreach (var block in impl.Blocks) { //var block = impl.Blocks.FirstOrDefault(); var newCmds = new List <Cmd>(); foreach (var cmd in block.cmds) { if (cmd is AssignCmd) { var asnCmd = cmd as AssignCmd; var rhs = asnCmd.Rhss.FirstOrDefault(); if (rhs is NAryExpr) { var fcExpr = rhs as NAryExpr; if (fcExpr.Fun.FunctionName.StartsWith("$load") || fcExpr.Fun.FunctionName.StartsWith("$store")) { char[] delim = { '.' }; var type = fcExpr.Fun.FunctionName.Split(delim)[1]; var size = 0; if (type == "ref") { size = 8; } else { size = Int32.Parse(type.Substring(1)) / 8; } var ptr = fcExpr.Args[1]; //Console.WriteLine(ptr.ToString()); var sizeExpr = Expr.Ident(size.ToString(), btype.Int); var paramList = new List <Expr>(); paramList.Add(ptr); paramList.Add(sizeExpr); var callCmd = new CallCmd(Token.NoToken, "__SMACK_check_memory_safety", paramList, new List <IdentifierExpr>()); newCmds.Add(callCmd); } } } if (cmd is CallCmd) { var callCmd = cmd as CallCmd; if (callCmd.callee.StartsWith("corral_fix_context_")) { continue; } } if (cmd is AssertCmd) { continue; } newCmds.Add(cmd); } block.cmds = newCmds; } } BoogieUtil.PrintProgram(program, args[1]); return; } if (visualizeHeap) { Procedure printProc = program.TopLevelDeclarations.OfType <Procedure>().Where(x => x.Name == "boogie_si_record_ref").FirstOrDefault(); foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()) { if (impl.Name.StartsWith("__SMACK_static_init")) { continue; } foreach (var block in impl.Blocks) { //var block = impl.Blocks.FirstOrDefault(); var newCmds = new List <Cmd>(); foreach (var cmd in block.cmds) { if (cmd is AssignCmd) { var asnCmd = cmd as AssignCmd; var rhs = asnCmd.Rhss.FirstOrDefault(); if (rhs is NAryExpr) { var fcExpr = rhs as NAryExpr; if (fcExpr.Fun.FunctionName.StartsWith("$load")) { var region = fcExpr.Args[0]; if (region.ToString().Equals("$M.0")) { var val = asnCmd.Lhss.FirstOrDefault().AsExpr; var ptr = fcExpr.Args[1]; List <Expr> paramList = new List <Expr>(); paramList.Add(val); var callCmd = new CallCmd(Token.NoToken, "boogie_si_record_ref", paramList, new List <IdentifierExpr>()); List <Object> attrib = new List <Object>(); attrib.Add(val.ToString()); callCmd.Attributes = new QKeyValue(Token.NoToken, "cexpr", attrib, callCmd.Attributes); newCmds.Add(cmd); newCmds.Add(callCmd); continue; } } if (fcExpr.Fun.FunctionName.StartsWith("$store")) { var region = fcExpr.Args[0]; if (region.ToString().Equals("$M.0")) { var val = fcExpr.Args[2]; List <Expr> paramList = new List <Expr>(); paramList.Add(val); var callCmd = new CallCmd(Token.NoToken, "boogie_si_record_ref", paramList, new List <IdentifierExpr>()); List <Object> attrib = new List <Object>(); attrib.Add(val.ToString()); callCmd.Attributes = new QKeyValue(Token.NoToken, "cexpr", attrib, callCmd.Attributes); newCmds.Add(callCmd); } } } } newCmds.Add(cmd); } block.cmds = newCmds; } } BoogieUtil.PrintProgram(program, args[1]); return; } if (printCallGraph) { PrintCallGraphToDot(program, "i386_immediate", "callgraph.dot"); return; } // Preprocess program: count lines + replace Root program = preProcess(program, count || onlyCount, oldRoot, newRoot); if (onlyCount) { return; } // Process it program = Process(program); // write the output BoogieUtil.PrintProgram(program, args[1]); }