Esempio n. 1
0
 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>();
 }
Esempio n. 2
0
        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> >();
        }
Esempio n. 3
0
 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;
     }
 }
Esempio n. 4
0
        // 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));
            }
        }