Пример #1
0
        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));
        }
Пример #2
0
        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);
        }
Пример #3
0
        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\"");
                }
            }
        }
Пример #4
0
        // 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);
        }
Пример #5
0
        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));
        }
Пример #6
0
        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));
        }
Пример #7
0
        //////////////////////////////////////////////
        // 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());
        }
Пример #8
0
        // 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));
        }
Пример #9
0
        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;
                    }
                }
            }
        }
Пример #10
0
        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);
        }
Пример #11
0
        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));
        }
Пример #12
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;
     }
 }
Пример #13
0
        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 = "";
                }
            }
        }
Пример #14
0
        // 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();
            }
        }
Пример #17
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);
            }
        }
Пример #18
0
 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);
 }
Пример #20
0
 public override bool checkPath(PersistentCBAProgram prog, VarSet trackedVars)
 {
     return(CBADriver.checkPath(prog, trackedVars));
 }
Пример #21
0
        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);
        }