public StormInstrumentationPass() { passName = "Storm instrumentation"; pinfo = null; policy = null; vmgr = null; inst = null; tinfo_instrument = new InsertionTrans(); tinfo_async = new InsertionTrans(); blockExecutionContextMap = new Dictionary <string, int>(); }
public RestrictToTrace(Program p, InsertionTrans t) { inp = p; usedNames = new Dictionary <string, int>(); nameToImpl = BoogieUtil.nameImplMapping(inp); nameToProc = BoogieUtil.nameProcMapping(inp); calledProcsNoImpl = new HashSet <string>(); output = new Program(); tinfo = t; newFixedContextProcs = new HashSet <int>(); addRaiseExceptionProcDecl = false; concretizeConstantToCall = new Dictionary <string, int>(); uvalueToConstants = new Dictionary <string, HashSet <Constant> >(); }
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; } }
// 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 ErrorTrace mapBackTrace(ErrorTrace trace, InsertionTrans tinfo) { // Output to be constructed var ret = new ErrorTrace(tinfo.getSrcProcName(trace.procName)); // The current block being constructed ErrorTraceBlock curr = null; foreach (var blk in trace.Blocks) { if (toFromBlockMap.ContainsKey(blk.blockName)) { // This "blk" corresponds to some block in the source program, // then start a new block here. if (curr != null) { ret.addBlock(curr); } curr = new ErrorTraceBlock(toFromBlockMap[blk.blockName]); if (blk.info != null) { curr.info = blk.info.Copy(); } } for (int i = 0; i < blk.Cmds.Count; i++) { var toType = InstrTypeEnum.INTRA; string callee = null; if (blk.Cmds[i].isCall()) { var cc = (blk.Cmds[i] as CallInstr); callee = cc.callee; if (cc.asyncCall) { toType = InstrTypeEnum.ASYNC; } else { toType = InstrTypeEnum.CALL; } } var to = new InstrLocation(blk.blockName, i, new InstrType(toType, callee)); // Is there a corresponding source instruction? if (!toFromMap.ContainsKey(to)) { continue; } // This is the location of the corresponding source instruction var from = toFromMap[to]; // This is the source instruction var inst = getCorrespondingInst(from, blk.Cmds[i], tinfo); // Now we have to place "inst" in "ret" addToTrace(inst, from, ref curr, ret); } } if (curr != null) { ret.addBlock(curr); } if (trace.returns) { ret.addReturn(trace.raisesException); } return(ret); }
private ErrorTraceInstr getCorrespondingInst(InstrLocation from, ErrorTraceInstr toInstr, InsertionTrans tinfo) { if (from.type.type == InstrTypeEnum.CALL || from.type.type == InstrTypeEnum.ASYNC) { // Get callee trace ErrorTrace calleeTrace = null; if (toInstr.isCall()) { calleeTrace = (toInstr as CallInstr).calleeTrace; } // recursively mapBack the callee trace if (calleeTrace != null) { calleeTrace = tinfo.mapBackTrace(calleeTrace); } return(new CallInstr(from.type.callee, calleeTrace, (from.type.type == InstrTypeEnum.ASYNC ? true : false), toInstr.info)); } else { return(new IntraInstr(toInstr.info)); } }