Example #1
0
        public static PersistentProgram RunHoudiniPass(PersistentProgram prog)
        {
            Stats.resume("houdini");

            HashSet <Variable> templateVars = new HashSet <Variable>();
            List <Requires>    reqs         = new List <Requires>();
            List <Ensures>     enss         = new List <Ensures>();
            SimpleHoudini      houdini      = new SimpleHoudini(templateVars, reqs, enss, -1, -1);

            houdini.ExtractLoops = true;
            SimpleHoudini.fastRequiresInference = false;
            //SimpleHoudini.checkAsserts = true;
            houdini.printHoudiniQuery = null; // "candidates.bpl";
            // turnning on several switches: InImpOutNonNull + InNonNull infer most assertions
            houdini.InImpOutNonNull = false;
            houdini.InImpOutNull    = false;
            houdini.InNonNull       = false;
            houdini.OutNonNull      = false;
            houdini.addContracts    = false;

            prog.writeToFile("beforeHoudini.bpl");
            PersistentProgram newP = houdini.run(prog);

            newP.writeToFile("afterHoudini.bpl");

            //BoogieUtil.PrintProgram(newP.getProgram(), "afterHoudini.bpl");
            Utils.Print("End Houdini Pass ...");
            Stats.stop("houdini");

            return(newP);
        }
Example #2
0
        // Run Alias Analysis on a sequential Boogie program
        // and returned the pruned program
        public static PersistentProgram RunAliasAnalysis(PersistentProgram inp, bool pruneEP = true)
        {
            var newinp = inp;

            if (Options.unrollDepth > 0)
            {
                Stats.resume("unroll");

                var unrp = new cba.LoopUnrollingPass(Options.unrollDepth);
                newinp = unrp.run(newinp);

                Stats.stop("unroll");
            }

            var program = newinp.getProgram();

            //AliasAnalysis.AliasAnalysis.dbg = true;
            //AliasAnalysis.AliasConstraintSolver.dbg = true;
            AliasAnalysis.AliasAnalysisResults res = null;
            if (Options.UseAliasAnalysisForAssertions)
            {
                // Do SSA
                program =
                    SSA.Compute(program, PhiFunctionEncoding.Verifiable, new HashSet <string> {
                    "int"
                });

                if (Options.inlineDepth > 0)
                {
                    Stats.resume("inlining");

                    Stats.resume("read.write");
                    program = BoogieUtil.ReResolveInMem(program);
                    Stats.stop("read.write");

                    var op = CommandLineOptions.Clo.InlineDepth;
                    CommandLineOptions.Clo.InlineDepth = Options.inlineDepth;

                    cba.InliningPass.InlineToDepth(program);

                    CommandLineOptions.Clo.InlineDepth = op;

                    RemoveHavocs(program);

                    Stats.stop("inlining");
                }

                /* TODO: Is this needed?
                 * Stats.resume("read.write");
                 * program = BoogieUtil.ReResolveInMem(program);
                 * Stats.stop("read.write");
                 */

                // Make sure that aliasing queries are on identifiers only
                var af =
                    AliasAnalysis.SimplifyAliasingQueries.Simplify(program);

                Stats.resume("fixpoint");
                res =
                    AliasAnalysis.AliasAnalysis.DoAliasAnalysis(program);
                Stats.stop("fixpoint");
            }
            else
            {
                // Make sure that aliasing queries are on identifiers only
                var af =
                    AliasAnalysis.SimplifyAliasingQueries.Simplify(program);

                res = new AliasAnalysis.AliasAnalysisResults();
                af.Iter(s => res.aliases.Add(s, true));
            }

            var origProgram = inp.getProgram();

            AliasAnalysis.PruneAliasingQueries.Prune(origProgram, res);

            if (pruneEP)
            {
                PruneRedundantEntryPoints(origProgram);
            }

            return(new PersistentProgram(origProgram, inp.mainProcName, inp.contextBound));
        }
Example #3
0
        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);
            }
        }
Example #4
0
        // Replace "assume x == NULL" with "assume x == NULL; assert false;"
        // provided x can indeed alias NULL
        // Also returns a map from allocation_site to possible branches affected by it
        public static Tuple <Program, Dictionary <int, HashSet <int> > > Run(Program program, string ep, bool useAA, bool injectAssert)
        {
            var ib = new InstrumentBranches(program, useAA, injectAssert);

            ib.instrument(ep);

            if (!useAA)
            {
                Console.WriteLine("For deadcode detection, we added {0} angelic assertions", ib.assertsAdded);
                return(Tuple.Create <Program, Dictionary <int, HashSet <int> > >(program, null));
            }

            var inp = new PersistentProgram(program, ep, 1);
            //inp.writeToFile("progbefore.bpl");

            // Make sure that aliasing queries are on identifiers only
            var af =
                AliasAnalysis.SimplifyAliasingQueries.Simplify(program);

            // Do SSA
            program =
                SSA.Compute(program, PhiFunctionEncoding.Verifiable, new HashSet <string> {
                "int"
            });

            //BoogieUtil.PrintProgram(program, "b3.bpl");

            // Run AA
            AliasAnalysis.AliasAnalysisResults res =
                AliasAnalysis.AliasAnalysis.DoAliasAnalysis(program);

            // allocation site of null
            var nil = res.allocationSites[ib.nullQuery.Name].FirstOrDefault();

            Debug.Assert(nil != null);

            var deadcodeAssertId = 0;

            // add the assert false OR assume reach(true)
            var MkAssertFalse = new Func <int, PredicateCmd>(i =>
            {
                var acmd = injectAssert ? BoogieAstFactory.MkAssert(Expr.False) as PredicateCmd :
                           new AssumeCmd(Token.NoToken,
                                         new NAryExpr(Token.NoToken, new FunctionCall(ib.reach), new List <Expr> {
                    Expr.True
                })) as PredicateCmd;

                acmd.Attributes = new QKeyValue(Token.NoToken,
                                                "deadcode", new List <object> {
                    Expr.Literal(i)
                }, null);

                return(acmd);
            });

            // build a map from AA allocation sites to allocation_site id
            var as2id = new Dictionary <string, HashSet <int> >();

            foreach (var tup in ib.allocationSite2Func)
            {
                var asites = res.allocationSites[tup.Value.Name];
                asites.Where(s => !as2id.ContainsKey(s)).Iter(s => as2id.Add(s, new HashSet <int>()));
                asites.Iter(s => as2id[s].Add(tup.Key));
            }

            if (AliasAnalysis.AliasConstraintSolver.environmentPointersUnroll != 0)
            {
                Console.WriteLine("AA Warning: EnvironmentPointersUnroll is non-zero, which means that the dependency information for deadcode branches is not sound.");
                Console.WriteLine("AA Warning: We currently rely on: forall unknown allocation sites that return a, ReachableAllocationSitesViaFields(a) = {a}.");
            }

            // map from allocation_site to possible branches affected by it
            var depInfo = new Dictionary <int, HashSet <int> >();

            program = inp.getProgram();
            var id = 0; var added = 0;

            foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
            {
                foreach (var blk in impl.Blocks)
                {
                    blk.Cmds.RemoveAll(c => (c is AssumeCmd) && QKeyValue.FindBoolAttribute((c as AssumeCmd).Attributes, "ForDeadCodeDetection"));

                    var ncmds = new List <Cmd>();
                    for (int i = 0; i < blk.Cmds.Count; i++)
                    {
                        ncmds.Add(blk.Cmds[i]);
                        var acmd = blk.Cmds[i] as AssumeCmd;
                        if (acmd == null)
                        {
                            continue;
                        }

                        id++;
                        if (!ib.id2Func.ContainsKey(id))
                        {
                            continue;
                        }

                        var asites = res.allocationSites[ib.id2Func[id].Name];
                        //if (!Options.disbleDeadcodeOpt || !asites.Contains(nil) && asites.Count != 0)
                        {
                            var assertid = deadcodeAssertId++;
                            ncmds.Add(MkAssertFalse(assertid));

                            // compute dependent allocations for this branch
                            var dep = new HashSet <int>();
                            asites.Where(a => as2id.ContainsKey(a))
                            .Iter(a => dep.UnionWith(as2id[a]));

                            dep.Where(d => !depInfo.ContainsKey(d))
                            .Iter(d => depInfo.Add(d, new HashSet <int>()));

                            dep.Iter(d => depInfo[d].Add(assertid));

                            added++;
                        }
                        //i++;
                    }
                    blk.Cmds = ncmds;
                }
            }
            //BoogieUtil.PrintProgram(program, "progafter.bpl");

            Console.WriteLine("For deadcode detection, we added {0} angelic assertions", added);
            return(Tuple.Create(program, depInfo));
        }
Example #5
0
        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();

            try
            {
                // Get the program, install the harness and do basic instrumentation
                var inprog  = GetProgram(args[0]);
                var program = new PersistentProgram(inprog, AvnAnnotations.CORRAL_MAIN_PROC, 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);

                // Run alias analysis
                Stats.resume("alias.analysis");
                Console.WriteLine("Running alias analysis");
                program = RunAliasAnalysis(program);
                Stats.stop("alias.analysis");

                Utils.Print(string.Format("#AssertsAfterAA : {0}", AssertCountVisitor.Count(program.getProgram())), Utils.PRINT_TAG.AV_STATS);

                // run Houdini pass
                if (Options.HoudiniPass)
                {
                    Utils.Print("Running Houdini Pass");
                    program = RunHoudiniPass(program);
                    Utils.Print(string.Format("#Asserts : {0}", AssertCountVisitor.Count(program.getProgram())), Utils.PRINT_TAG.AV_STATS);
                }

                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);
            }
        }
        public override CBAProgram runCBAPass(CBAProgram program)
        {
            // Add blanks
            blanksInfo = AddBlanks(program);

            // Remove unreachable procedures
            BoogieUtil.pruneProcs(program, program.mainProcName);

            if (!Options.TraceSlicing)
            {
                // Remove source line annotations
                sourceInfo = cba.PrintSdvPath.DeleteSourceInfo(program);
            }
            else
            {
                sourceInfo = null;
            }

            // Remove print info
            //printInfo = cba.PrintSdvPath.DeletePrintCmds(program);

            // Compress
            compressBlocks.VisitProgram(program);

            // name Ebasic
            NameEnvironmentConstraints(program);

            // Instrument assertions
            int tokenId = 0;

            origMainName = program.mainProcName;

            CBAProgram ret = null;

            if (!Options.DeepAsserts)
            {
                // Do error-bit instrumentation
                var impls = BoogieUtil.nameImplMapping(program);
                var pwa   = cba.SequentialInstrumentation.procsWithAsserts(program);

                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                {
                    var instrumented = new List <Block>();
                    foreach (var blk in impl.Blocks)
                    {
                        var currCmds  = new List <Cmd>();
                        var currLabel = blk.Label;

                        assertInstrInfo.addTrans(impl.Name, blk.Label, blk.Label);
                        var incnt = -1;
                        foreach (Cmd cmd in blk.Cmds)
                        {
                            incnt++;

                            // instrument assert
                            if (cmd is AssertCmd && !BoogieUtil.isAssertTrue(cmd))
                            {
                                currCmds.Add(BoogieAstFactory.MkVarEqExpr(assertsPassed, (cmd as AssertCmd).Expr));

                                var token = new AssertToken(tokenId);
                                originalAssertions.Add(token, cmd as AssertCmd);
                                tokenLocation.Add(token, Tuple.Create(impl.Name, currLabel));
                                procToTokens.InitAndAdd(impl.Name, token);

                                addedTrans(impl.Name, blk.Label, incnt, cmd, currLabel, currCmds);

                                currLabel = addInstr(instrumented, currCmds, currLabel, tokenId);
                                tokenId++;
                                currCmds = new List <Cmd>();

                                continue;
                            }

                            // procedure call
                            if (cmd is CallCmd && pwa.Contains((cmd as CallCmd).callee))
                            {
                                currCmds.Add(cmd);
                                addedTrans(impl.Name, blk.Label, incnt, cmd, currLabel, currCmds);
                                currLabel = addInstr(instrumented, currCmds, currLabel, -1);
                                currCmds  = new List <Cmd>();
                                continue;
                            }

                            currCmds.Add(cmd);
                            addedTrans(impl.Name, blk.Label, incnt, cmd, currLabel, currCmds);
                        }

                        instrumented.Add(new Block(Token.NoToken, currLabel, currCmds, blk.TransferCmd));
                    }

                    impl.Blocks = instrumented;
                }

                program.AddTopLevelDeclaration(assertsPassed);
                var newMain = addMain(program);

                BoogieUtil.DoModSetAnalysis(program);

                // Set inline attribute
                // free requires assertsPassed == true;
                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                {
                    impl.Proc.Requires.Add(new Requires(true, Expr.Ident(assertsPassed)));
                }

                // convert free ensures e to:
                //  free ensures assertsPassed == false || e
                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()
                         .Where(impl => pwa.Contains(impl.Name)))
                {
                    foreach (Ensures ens in impl.Proc.Ensures)
                    {
                        ens.Condition = Expr.Or(Expr.Not(Expr.Ident(assertsPassed)), ens.Condition);
                    }
                }

                currProg = program;
                ret      = new CBAProgram(program, newMain, 0);
            }
            else
            {
                // Use Deep-assert instrumentation
                da = new cba.DeepAssertRewrite();

                // First, tag assertions with tokens
                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                {
                    foreach (var blk in impl.Blocks)
                    {
                        foreach (var cmd in blk.Cmds.OfType <AssertCmd>())
                        {
                            if (BoogieUtil.isAssertTrue(cmd))
                            {
                                continue;
                            }

                            var token = new AssertToken(tokenId);
                            cmd.Attributes = new QKeyValue(Token.NoToken, "avn", new List <object> {
                                Expr.Literal(tokenId)
                            },
                                                           cmd.Attributes);
                            originalAssertions.Add(token, cmd);
                            tokenLocation.Add(token, Tuple.Create(impl.Name, blk.Label));
                            procToTokens.InitAndAdd(impl.Name, token);
                            tokenId++;
                        }
                    }
                }

                // Second, do the rewrite
                var t1     = new PersistentProgram(program, program.mainProcName, program.contextBound);
                var t2     = da.run(t1);
                var daprog = t2.getCBAProgram();

                // Third, revisit the assertions and remember their location
                // in the output program. This is a bit of a hack. The "tokenLocation"
                // of a token is the pair (p1,b1) where p1 is the procedure the assertion
                // originally came from and b1 is the block in the new main that contains
                // that assertion.
                var main = BoogieUtil.findProcedureImpl(daprog.TopLevelDeclarations, daprog.mainProcName);
                foreach (var block in main.Blocks)
                {
                    foreach (var cmd in block.Cmds.OfType <AssertCmd>())
                    {
                        var tok = QKeyValue.FindIntAttribute(cmd.Attributes, "avn", -1);
                        if (tok < 0)
                        {
                            continue;
                        }
                        var token = new AssertToken(tok);

                        Debug.Assert(tokenLocation.ContainsKey(token));
                        var oldloc = tokenLocation[token];
                        tokenLocation[token] = Tuple.Create(oldloc.Item1, block.Label);
                    }
                }

                currProg = daprog;
                ret      = daprog;
            }

            return(ret);
        }