public static bool checkPath(PersistentCBAProgram pmeta, VarSet trackedVars, out ErrorTrace trace) { PersistentCBAProgram temp; InsertionTrans temp2; return(checkPath(pmeta, trackedVars, true, out temp, out temp2, out trace)); }
public override bool checkPath(PersistentCBAProgram prog, VarSet trackedVars) { ConfigManager.beginPathVerification(false); // Do variable slicing, inlining and verify var abs = new VariableSlicePass(trackedVars); prog = abs.run(prog); VerificationPass verify = null; if (GlobalConfig.useLocalVariableAbstraction) { verify = new StaticInlineAndVerifyPass(new StaticSettings(-1, 1), false); } else { verify = new VerificationPass(false); } try { verify.run(prog); } catch (Exception) { ConfigManager.endPathVerification(); throw; } ConfigManager.endPathVerification(); return(verify.success); }
private static void setupPrint(PersistentCBAProgram program, ErrorTrace trace, string file) { // Set output files pathFile = file == null ? null : new TokenTextWriter(file + "_trace.txt"); if (pathFile != null) { program.writeToFile(file + ".bpl"); } Program prog = program.getProgram(); // Initialization initialize(prog, trace, file == null ? null : file + ".bpl"); if (pathFile != null) { if (traceFormat == TraceFormat.ConcurrencyExplorer) { pathFile.WriteLine("s"); pathFile.WriteLine("#"); } else if (traceFormat == TraceFormat.SDV) { pathFile.WriteLine("0 \"?\" 0 false ^ Call \"OS\" \"main\""); } } }
// Given a set of candidate procedures, find out which of them can be reached public HashSet <string> iterateComputation(PersistentCBAProgram program, HashSet <string> candidates) { var ret = new HashSet <string>(); // Instrument the program. // instrument() sets labelProcMap var newProg = instrument(program, candidates); var verifier = getVerifier(); verifier.run(newProg); // Nothing more can be covered if (verifier.success) { return(ret); } // All these guys were covered foreach (var trace in verifier.traces) { // trace.getProcs().Iter(s => ret.Add(s)); ret.UnionWith(trace.getProcs()); } ret = HashSetExtras <string> .Intersection(ret, candidates); Log.WriteLine(Log.Normal, string.Format("Coverage: Got {0} traces and {1} procs", verifier.traces.Count, ret.Count)); return(ret); }
private PersistentCBAProgram instrument(PersistentCBAProgram pprogram, HashSet <string> candidates) { var program = pprogram.getProgram(); foreach (var decl in program.TopLevelDeclarations) { if (!(decl is Implementation)) { continue; } var impl = decl as Implementation; // Create two blocks at the start of the implementation: // newStart: // goto lab,origStart; // // lab: // assert false; // return; // var lab = getNewLabel(); var targets1 = new List <String>(); targets1.Add(lab); targets1.Add(impl.Blocks[0].Label); var blk1 = new Block(Token.NoToken, getNewLabel(), new List <Cmd>(), new GotoCmd(Token.NoToken, targets1)); var blk2cmds = new List <Cmd>(); blk2cmds.Add(new AssertCmd(Token.NoToken, Expr.Literal(false))); var blk2 = new Block(Token.NoToken, lab, blk2cmds, new ReturnCmd(Token.NoToken)); // Get rid of original asserts // TODO: This works with the CBA reduction?? foreach (var blk in impl.Blocks) { for (int i = 0, n = blk.Cmds.Count; i < n; i++) { if (blk.Cmds[i] is AssertCmd) { var c = (blk.Cmds[i] as AssertCmd).Expr; blk.Cmds[i] = new AssumeCmd(Token.NoToken, c); } } } // Put in the new blocks var newBlocks = new List <Block>(); newBlocks.Add(blk1); newBlocks.AddRange(impl.Blocks); newBlocks.Add(blk2); impl.Blocks = newBlocks; } return(new PersistentCBAProgram(program, pprogram.mainProcName, pprogram.contextBound)); }
public static bool checkPath(PersistentCBAProgram pmeta, VarSet trackedVars) { PersistentCBAProgram temp; ErrorTrace temp2; InsertionTrans temp3; return(checkPath(pmeta, trackedVars, false, out temp, out temp3, out temp2)); }
////////////////////////////////////////////// // Private guys -- need not bother about these ////////////////////////////////////////////// protected override Program getInput(ProgTransformation.PersistentProgram inp) { PersistentCBAProgram ap = inp as PersistentCBAProgram; Debug.Assert(ap != null); return(ap.getCBAProgram()); }
// Remove all procs in "procsToRemove" from the program, and replace calls to these procedures by // assume false public static PersistentCBAProgram prune(PersistentCBAProgram pprogram, HashSet <string> procsToRemove) { if (procsToRemove.Count == 0) { return(pprogram); } // Go through all Commands and remove calls CBAProgram program = pprogram.getCBAProgram(); foreach (var decl in program.TopLevelDeclarations) { if (!(decl is Implementation)) { continue; } var impl = decl as Implementation; foreach (Block blk in impl.Blocks) { for (int i = 0; i < blk.Cmds.Count; i++) { if (isCall(blk.Cmds[i], procsToRemove)) { blk.Cmds[i] = new AssumeCmd(Token.NoToken, Expr.False); } } } } // Remove declarations and implementations var newDecls = new List <Declaration>(); foreach (var decl in program.TopLevelDeclarations) { if (decl is Implementation) { if (procsToRemove.Contains((decl as Implementation).Name)) { continue; } } else if (decl is Procedure) { if (procsToRemove.Contains((decl as Procedure).Name)) { continue; } } newDecls.Add(decl); } program.TopLevelDeclarations = newDecls; return(new PersistentCBAProgram(program, program.mainProcName, program.contextBound)); }
private void doInlining(CBAProgram p) { inlineInput = new PersistentCBAProgram(p, p.mainProcName, p.contextBound); // Temporary fix for Boogie's bug while inlining calls // that have don't care expressions. This does not change the control // structure nor the number of commands per block -- hence, this transformation // need not be recorded. RewriteCallDontCares rdc = new RewriteCallDontCares(); rdc.VisitProgram(p); // Copy of OnlyBoogie.EliminateDeadVariablesAndInline var TopLevelDeclarations = p.TopLevelDeclarations; bool inline = false; foreach (Declaration d in TopLevelDeclarations) { if ((d is Procedure || d is Implementation) && d.FindExprAttribute("inline") != null) { inline = true; } } if (inline) { foreach (Declaration d in TopLevelDeclarations) { Implementation impl = d as Implementation; if (impl != null) { impl.OriginalBlocks = impl.Blocks; impl.OriginalLocVars = impl.LocVars; } } foreach (Declaration d in TopLevelDeclarations) { Implementation impl = d as Implementation; if (impl != null && !impl.SkipVerification) { Inliner.ProcessImplementation(p as Program, impl); } } foreach (Declaration d in TopLevelDeclarations) { Implementation impl = d as Implementation; if (impl != null) { impl.OriginalBlocks = null; impl.OriginalLocVars = null; } } } }
public PersistentCBAProgram run(PersistentCBAProgram inp) { var time1 = DateTime.Now; ProgTransformation.PersistentProgram outp = run(inp as ProgTransformation.PersistentProgram); var ret = outp as PersistentCBAProgram; var time2 = DateTime.Now; lastRun = (time2 - time1); return(ret); }
public static PersistentCBAProgram AddLoopBounds(PersistentCBAProgram program, Dictionary <string, int> extraRecBounds) { if (extraRecBounds.Count == 0 || extraRecBounds.All(tup => tup.Value == 0)) { return(program); } var prog = program.getCBAProgram(); AddLoopBounds(prog, extraRecBounds); return(new PersistentCBAProgram(prog, prog.mainProcName, prog.contextBound)); }
public static bool checkPath(PersistentCBAProgram prog, VarSet trackedVars, bool returnTrace, out PersistentCBAProgram pout, out InsertionTrans tinfo, out ErrorTrace cex) { ConfigManager.beginPathVerification(returnTrace); try { var ret = VerifyProgram(ref prog, trackedVars, returnTrace, out pout, out tinfo, out cex); ConfigManager.endPathVerification(); return(ret); } catch (Exception) { ConfigManager.endPathVerification(); throw; } }
public static void printCTrace(PersistentCBAProgram program, ErrorTrace trace, string file, bool printConsole) { //gatherCSourceLineInfo(origInFile); Debug.Assert(mapCTrace != null); LOC = 0; print(program, trace, file); if (!printConsole) { return; } Console.WriteLine("Execution trace:"); //Console.WriteLine("Format: filename(line,col): threadid, k"); var prev = ""; var extra = ""; foreach (var ev in events) { if (!ev.committed) { continue; } if (ev.extra != "") { extra += (extra == "" ? "" : ", ") + ev.extra; } var filename = sanitizeFileName(ev.filename); if (filename != null && filename != "") { //var str = string.Format("{0}({1},{2}): Thread={3} K={4}: {5}", filename, ev.lineno, 1, ev.tid, ev.k, ev.extra); var str = string.Format("{0}({1},{2}): Trace: Thread={3} ({4})", filename, ev.lineno, ev.col == -1? 1 : ev.col, ev.tid, extra); if (str != prev) { Console.WriteLine(str); } prev = str; extra = ""; } } }
// Given a set of candidate procedures, find out which of them lie // on an error path. This function is iterated until it returns the // empty set or the whole set of candidates public HashSet <string> iterateComputation(PersistentCBAProgram program, HashSet <string> candidates) { var ret = new HashSet <string>(); // Instrument the program. // instrument() sets labelProcMap var newProg = instrument(program, candidates); CommandLineOptions.Clo.ProverCCLimit = 5; var verifier = getVerifier(); verifier.run(newProg); if (verifier.success) { return(ret); } foreach (var trace in verifier.traces) { // Find the failing assert -- it must be in main var blkName = trace.Blocks.Last().blockName; if (labelProcMap.ContainsKey(blkName)) { ret.Add(labelProcMap[blkName]); } } foreach (var trace in verifier.traces) { // trace.getProcs().Iter(s => ret.Add(s)); ret.UnionWith(trace.getProcs()); } ret = HashSetExtras <string> .Intersection(ret, candidates); Log.WriteLine(Log.Normal, string.Format("EP: Got {0} traces and {1} procs", verifier.traces.Count, ret.Count)); return(ret); }
private static void setupPrint(PersistentCBAProgram program, ErrorTrace trace, string file) { // Set output files pathFile = file == null ? null : new TokenTextWriter(file + "_trace.txt"); if (pathFile != null) { program.writeToFile(file + ".bpl"); } Program prog = program.getProgram(); // Initialization initialize(prog, trace, file == null ? null : file + ".bpl"); if (pathFile != null) { pathFile.WriteLine("s"); } if (pathFile != null) { pathFile.WriteLine("#"); } }
// Print an interleaved trace, using the execution context information present // in trace public static void print(PersistentCBAProgram program, ErrorTrace trace, string file) { trace = trace.Copy(); ErrorTrace.fillInContextSwitchInfo(trace); printConsole = false; setupPrint(program, trace, file); collectAllEvents(trace); arrangeEvents(); // compute LOC var stks = new HashSet <string>(); foreach (var ev in events) { stks.Add(ev.filename + "::" + ev.lineno.ToString()); } LOC = stks.Count; // Print the failing assert foreach (var ev in events) { if (ev.extra.Contains("ASSERTION FAILS")) { Console.WriteLine("{0}({1},1): error PF5001: This assertion can fail", sanitizeFileName(ev.filename), ev.lineno); } } Console.WriteLine(); foreach (var ev in events) { ev.printEvent(); } if (pathFile != null) { pathFile.Close(); } }
// Verify prog while tracking only variables in trackedVars. // Returns true if no error is found. // Returns false if error is found. Returns counterexample via pout // If returnTrace is set to false, then pout is always null // (no counterexample generation is attempted) // cex: the error trace in prog (if there is one) // tinfo: the transformation carried out in going from prog to pout // Call this method via: checkProgram or checkPath private static bool VerifyProgram(ref PersistentCBAProgram prog, VarSet trackedVars, bool returnTrace, out PersistentCBAProgram pout, out InsertionTrans tinfo, out ErrorTrace cex) { PersistentCBAProgram curr = prog; pout = null; cex = null; tinfo = null; ////// // These are the compilation phases ////// VariableSlicePass cp1 = new VariableSlicePass(trackedVars); StormInstrumentationPass cp2 = null; var recordK = new HashSet <string>(); if (!GlobalConfig.isSingleThreaded) { cp2 = new StormInstrumentationPass(); } StaticInliningAndUnrollingPass cp3 = null; if (GlobalConfig.staticInlining > 0) { cp3 = new StaticInliningAndUnrollingPass(new StaticSettings(CommandLineOptions.Clo.RecursionBound, CommandLineOptions.Clo.RecursionBound)); } ContractInfer ciPass = null; // Run the source transformations curr = cp1.run(curr); if (cp2 != null) { curr = cp2.run(curr); } if (cp3 != null) { curr = cp3.run(curr); } // infer contracts if (GlobalConfig.InferPass != null) { ciPass = new ContractInfer(GlobalConfig.InferPass); ciPass.ExtractLoops = false; curr = ciPass.run(curr); Console.WriteLine("Houdini took {0} seconds", ciPass.lastRun.TotalSeconds.ToString("F2")); GlobalConfig.InferPass = null; // add summaries to the original program prog = ciPass.addSummaries(prog); } // record k and tid if (cp2 != null) { recordK.Add(cp2.varKName); recordK.Add(cp2.tidVarName); } if (GlobalConfig.varsToRecord.Count != 0) { recordK.UnionWith(GlobalConfig.varsToRecord); recordK.IntersectWith(trackedVars.Variables); } // Now verify VerificationPass cp4 = new VerificationPass(true, recordK); curr = cp4.run(curr); reachedBound = cp4.reachedBound; if (cp4.success) { // Program correct. return(true); } else if (!returnTrace) { return(false); } else { // Concretize the trace and see if its a real bug // Concretization: map back the trace to the original program var trace4 = cp4.trace; //PrintProgramPath.print(cp4.input as PersistentCBAProgram, trace4, "temp4"); if (ciPass != null) { trace4 = ciPass.mapBackTrace(trace4); } var trace3 = trace4; if (cp3 != null) { trace3 = cp3.mapBackTrace(trace4); } //PrintProgramPath.print(cp3.input as PersistentCBAProgram, trace3, "temp3"); var trace2 = trace3; if (cp2 != null) { trace2 = cp2.mapBackTrace(trace3); } var trace1 = cp1.mapBackTrace(trace2); //PrintProgramPath.print(cp1.input as PersistentCBAProgram, trace1, "temp1"); cex = trace1; // Restrict the program to the trace tinfo = new InsertionTrans(); var traceProgCons = new RestrictToTrace(cp1.input.getProgram(), tinfo); ErrorTrace.fillInContextSwitchInfo(trace1); traceProgCons.addTrace(trace1); pout = new PersistentCBAProgram(traceProgCons.getProgram(), traceProgCons.getFirstNameInstance(cp1.getInput().mainProcName), cp1.getInput().contextBound, ConcurrencyMode.FixedContext); //pout.writeToFile("pout.bpl"); return(false); } }
public InliningPass(int bound) { passName = "Inlining"; inlineInput = null; this.bound = bound; }
// Print an interleaved trace, using the execution context information present // in trace. Link the trace to the original C files from which the bpl file was obtained public static void printCTrace(PersistentCBAProgram program, ErrorTrace trace, string file) { printCTrace(program, trace, file, true); }
public override bool checkPath(PersistentCBAProgram prog, VarSet trackedVars) { return(CBADriver.checkPath(prog, trackedVars)); }
private PersistentCBAProgram instrument(PersistentCBAProgram pprogram, HashSet <string> candidates) { Debug.Assert(candidates.Count != 0); labelProcMap = new Dictionary <string, string>(); var program = pprogram.getProgram(); var nameImplMap = BoogieUtil.nameImplMapping(program); // Each candidate gets its own variable var procVars = new Dictionary <string, Variable>(); foreach (var str in candidates) { procVars.Add(str, new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "ep_var_" + str, Microsoft.Boogie.Type.Bool))); program.AddTopLevelDeclaration(procVars[str]); } // Add the new variables to each procedures' modifies clause foreach (var decl in program.TopLevelDeclarations) { if (decl is Implementation) { var impl = decl as Implementation; foreach (var str in candidates) { impl.Proc.Modifies.Add(new IdentifierExpr(Token.NoToken, procVars[str])); } } } // Instrument program foreach (var str in candidates) { var impl = nameImplMap[str]; var ncmds = new List <Cmd>(); ncmds.Add(BoogieAstFactory.MkVarEqConst(procVars[str], false)); ncmds.AddRange(impl.Blocks[0].Cmds); impl.Blocks[0].Cmds = ncmds; } // Instrument main. // -- Assign true to the new variables // -- Change the assert // (We assume that main only has one assert) var mainImpl = nameImplMap[pprogram.mainProcName]; var newCmds = new List <Cmd>(); foreach (var str in candidates) { newCmds.Add(BoogieAstFactory.MkVarEqConst(procVars[str], true)); } newCmds.AddRange(mainImpl.Blocks[0].Cmds); mainImpl.Blocks[0].Cmds = newCmds; // Find the assert Block blkWithAssert = null; AssertCmd assertCmd = null; bool found = false; foreach (var blk in mainImpl.Blocks) { found = false; foreach (var cmd in blk.Cmds) { if (cmd is AssertCmd) { assertCmd = cmd as AssertCmd; found = true; break; } } if (found) { blkWithAssert = blk; break; } } Debug.Assert(blkWithAssert != null); // Construct the new blocks var newLabs = new Dictionary <string, string>(); var restLab = getNewLabel(); foreach (var str in candidates) { newLabs.Add(str, getNewLabel()); var tcmds = new List <Cmd>(); tcmds.Add(new AssertCmd(Token.NoToken, Expr.Or(Expr.Ident(procVars[str]), assertCmd.Expr))); mainImpl.Blocks.Add(new Block(Token.NoToken, newLabs[str], tcmds, BoogieAstFactory.MkGotoCmd(restLab))); } // change blkWithAssert to include only commands upto the assert // Add the rest of commands to a new block found = false; newCmds = new List <Cmd>(); var newBlk = new Block(Token.NoToken, restLab, new List <Cmd>(), blkWithAssert.TransferCmd); foreach (Cmd cmd in blkWithAssert.Cmds) { if (cmd is AssertCmd) { found = true; continue; } if (!found) { newCmds.Add(cmd); } else { newBlk.Cmds.Add(cmd); } } blkWithAssert.Cmds = newCmds; var targets = new List <String>(newLabs.Values.ToArray()); blkWithAssert.TransferCmd = new GotoCmd(Token.NoToken, targets); mainImpl.Blocks.Add(newBlk); var ret = new PersistentCBAProgram(program, pprogram.mainProcName, pprogram.contextBound); //ret.writeToFile("ep_instrumented.bpl"); return(ret); }