예제 #1
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\"");
                }
            }
        }
예제 #2
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));
        }
        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("#");
            }
        }
예제 #4
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);
        }
예제 #5
0
        private ErrorTrace mapBackTraceInline(ErrorTrace trace)
        {
            Debug.Assert(trace.isIntra());

            Program inputProg = inlineInput.getProgram();

            var nameImplMap = BoogieUtil.nameImplMapping(inputProg);
            var traceLabels = trace.getBlockLabels();

            var            stack     = new List <WorkItemR>();
            Implementation startImpl = getImpl(trace.procName, nameImplMap);

            Debug.Assert(traceLabels[0] == startImpl.Blocks[0].Label);
            var curr = new WorkItemR(startImpl, traceLabels[0]);

            // This variable keeps our current position in traceLabels
            int ecount = 0;
            // This variable keeps our current position in traceLabels[ecount].Cmds
            int icount = 0;

            var ret = new ErrorTrace(trace.procName);

            ret.addBlock(new ErrorTraceBlock(traceLabels[0]));

            // We will walk over the input program, trying to cover the same path as
            // trace, knowing that trace represents an inlined path
            while (true)
            {
                // Reached the end of the path?
                if (ecount == traceLabels.Count)
                {
                    break;
                }

                //Console.WriteLine(curr.impl.Name + ": " + curr.label);

                // Reached the end of the current block?
                if (curr.count == curr.block.Cmds.Count)
                {
                    ecount++;
                    icount = 0;
                    if (ecount == traceLabels.Count)
                    {
                        break;
                    }

                    // Move onto the next block
                    TransferCmd tc = curr.block.TransferCmd;
                    if (tc is ReturnCmd)
                    {
                        ret.addReturn();

                        if (stack.Count == 0)
                        {
                            // We're done
                            Debug.Assert(ecount == traceLabels.Count);
                            break;
                        }
                        curr = stack[0];
                        stack.RemoveAt(0);

                        // An inlined procedure ends with "Return" label
                        Debug.Assert(inlinedLabelMatches("Return", traceLabels[ecount]));

                        ecount++;
                        icount = 0;
                        Debug.Assert(traceLabels[ecount].Contains(curr.block.Label));

                        continue;
                    }

                    if (tc is GotoCmd)
                    {
                        List <String> targets = (tc as GotoCmd).labelNames;
                        string        target  = matchInlinedLabelNames(targets, traceLabels[ecount]);
                        curr = new WorkItemR(curr.impl, target);
                        ret.addBlock(new ErrorTraceBlock(curr.label));
                        continue;
                    }

                    // Unknown transfer command
                    Debug.Assert(false);
                }

                // We have to continue in the same block
                Cmd c = curr.block.Cmds[curr.count];
                curr.count++;

                if (!(c is CallCmd))
                {
                    ret.addInstr(new IntraInstr(getInfo(trace, ecount, icount)));
                    icount++;
                    continue;
                }

                // We're at a procedure call
                CallCmd cc = c as CallCmd;

                // If this is a call to a procedure without implementation, then skip
                if (!nameImplMap.ContainsKey(cc.Proc.Name))
                {
                    ret.addInstr(new CallInstr(cc.Proc.Name, null, false, getInfo(trace, ecount, icount)));
                    icount++;
                    continue;
                }

                Implementation callee = getImpl(cc.Proc.Name, nameImplMap);
                string         label  = callee.Blocks[0].Label;
                // The first label in a inlined procedure is always called Entry
                ecount++;
                Debug.Assert(inlinedLabelMatches("Entry", traceLabels[ecount]));

                ecount++;
                icount = 0;
                Debug.Assert(inlinedLabelMatches(label, traceLabels[ecount]));

                WorkItemR next = new WorkItemR(callee, label);
                stack.Insert(0, curr);
                curr = next;

                ret.addCall(callee.Name);
                ret.addBlock(new ErrorTraceBlock(curr.label));
            }
            return(ret);
        }