Exemplo n.º 1
0
        /// <summary>
        /// Populates the divergence information.
        /// </summary>
        /// <param name="example">The counter example.</param>
        /// <param name="error">The divergence error.</param>
        public void PopulateDivergenceInformation(CallCounterexample example, DivergenceError error)
        {
            CallCmd            call   = example.FailingCall;
            SourceLocationInfo source = new SourceLocationInfo(GetAttributes(call), GetSourceFileName(), call.tok);

            error.Location = source;
        }
Exemplo n.º 2
0
        private static Variable ExtractOffsetVar(CallCounterexample err)
        {
            var VFV = new VariableFinderVisitor(
                RaceInstrumentationUtil.MakeOffsetVariableName(QKeyValue.FindStringAttribute(err.FailingRequires.Attributes, "array"), GetAccessType(err)));

            VFV.Visit(err.FailingRequires.Condition);
            return(VFV.GetVariable());
        }
Exemplo n.º 3
0
        //private readonly Dictionary<IToken, List<ErrorCode>> reportedVerificationErrors = new Dictionary<IToken, List<ErrorCode>>();
        //private readonly List<string> errors = new List<string>();

        public void ReportCounterexample(Counterexample ce, string message)
        {
            if (message != null)
            {
                message = " (" + message + ")";
            }
            else
            {
                message = "";
            }

            try {
                ReturnCounterexample /*?*/ rce = ce as ReturnCounterexample;
                if (rce != null)
                {
                    IToken tok = rce.FailingReturn.tok;
                    for (int i = rce.Trace.Length - 1; i >= 0; i--)
                    {
                        foreach (Cmd c in rce.Trace[i].Cmds)
                        {
                            AssertCmd assrt = c as AssertCmd;
                            if (assrt != null)
                            {
                                NAryExpr nary = assrt.Expr as NAryExpr;
                                if (nary != null)
                                {
                                    FunctionCall fcall = nary.Fun as FunctionCall;
                                    if (fcall != null && fcall.FunctionName == "$position_marker")
                                    {
                                        tok = assrt.tok;
                                    }
                                }
                            }
                        }
                    }
                    ReportOutcomePostconditionFailed(rce.FailingEnsures.tok, tok, message);
                }
                AssertCounterexample /*?*/ ace = ce as AssertCounterexample;
                if (ace != null)
                {
                    ReportOutcomeAssertFailed(ace.FailingAssert.tok,
                                              (ace.FailingAssert is LoopInvMaintainedAssertCmd ? "Loop body invariant" :
                                               ace.FailingAssert is LoopInitAssertCmd ? "Loop entry invariant" : "Assertion"),
                                              message
                                              );
                }
                CallCounterexample /*?*/ cce = ce as CallCounterexample;
                if (cce != null)
                {
                    ReportOutcomePreconditionFailed(cce.FailingCall.tok, cce.FailingRequires, message);
                }
            } finally {
                if (commandLineOptions != null && commandLineOptions.PrintCEVModel)
                {
                    ce.PrintModel();
                }
            }
        }
Exemplo n.º 4
0
 private int ReportRequiresFailure(CallCounterexample cex)
 {
     Console.Error.WriteLine();
     ErrorReporter.ErrorWriteLine(cex.FailingCall + ":",
                                  "a precondition for this call might not hold", ErrorMsgType.Error);
     ErrorReporter.ErrorWriteLine(cex.FailingRequires.Line + ":",
                                  "this is the precondition that might not hold", ErrorMsgType.Note);
     return(1);
 }
Exemplo n.º 5
0
        private string ArrayOffsetString(CallCounterexample Cex, string RaceyArraySourceName)
        {
            Variable AccessOffsetVar      = ExtractOffsetVar(Cex);
            Variable AccessHasOccurredVar = ExtractAccessHasOccurredVar(Cex);
            string   StateName            = GetStateName(Cex);
            Model    Model = Cex.Model;

            return(ArrayOffsetString(Model, StateName, AccessHasOccurredVar, AccessOffsetVar, RaceyArraySourceName));
        }
Exemplo n.º 6
0
        private static AssumeCmd DetermineConflictingAction(CallCounterexample CallCex, string RaceyState, string AccessHasOccurred, string AccessOffset)
        {
            AssumeCmd LastLogAssume   = null;
            string    LastOffsetValue = null;

            foreach (var b in CallCex.Trace)
            {
                bool finished = false;
                foreach (var c in b.Cmds.OfType <AssumeCmd>())
                {
                    string StateName = QKeyValue.FindStringAttribute(c.Attributes, "captureState");
                    if (StateName == null)
                    {
                        continue;
                    }
                    Model.CapturedState state = GetStateFromModel(StateName, CallCex.Model);
                    if (state == null || state.TryGet(AccessHasOccurred) is Model.Uninterpreted)
                    {
                        // Either the state was not recorded, or the state has nothing to do with the reported error, so do not
                        // analyse it further.
                        continue;
                    }

                    Model.Boolean   AHO_value = state.TryGet(AccessHasOccurred) as Model.Boolean;
                    Model.BitVector AO_value  =
                        (RaceInstrumentationUtil.RaceCheckingMethod == RaceCheckingMethod.ORIGINAL
            ? state.TryGet(AccessOffset)
            : CallCex.Model.TryGetFunc(AccessOffset).GetConstant()) as Model.BitVector;

                    if (!AHO_value.Value)
                    {
                        LastLogAssume   = null;
                        LastOffsetValue = null;
                    }
                    else if (LastLogAssume == null || !AO_value.Numeral.Equals(LastOffsetValue))
                    {
                        LastLogAssume   = c;
                        LastOffsetValue = AO_value.Numeral;
                    }
                    if (StateName.Equals(RaceyState))
                    {
                        finished = true;
                    }
                    break;
                }
                if (finished)
                {
                    break;
                }
            }

            Debug.Assert(LastLogAssume != null);
            return(LastLogAssume);
        }
Exemplo n.º 7
0
 private static void DetermineNatureOfRace(CallCounterexample CallCex, out string raceName, out string access1, out string access2)
 {
     if (QKeyValue.FindBoolAttribute(CallCex.FailingRequires.Attributes, "write_read"))
     {
         raceName = "write-read";
         access1  = "Write";
         access2  = "Read";
     }
     else if (QKeyValue.FindBoolAttribute(CallCex.FailingRequires.Attributes, "read_write"))
     {
         raceName = "read-write";
         access1  = "Read";
         access2  = "Write";
     }
     else if (QKeyValue.FindBoolAttribute(CallCex.FailingRequires.Attributes, "write_write"))
     {
         raceName = "write-write";
         access1  = "Write";
         access2  = "Write";
     }
     else if (QKeyValue.FindBoolAttribute(CallCex.FailingRequires.Attributes, "atomic_read"))
     {
         raceName = "atomic-read";
         access1  = "Atomic";
         access2  = "Read";
     }
     else if (QKeyValue.FindBoolAttribute(CallCex.FailingRequires.Attributes, "atomic_write"))
     {
         raceName = "atomic-write";
         access1  = "Atomic";
         access2  = "Write";
     }
     else if (QKeyValue.FindBoolAttribute(CallCex.FailingRequires.Attributes, "read_atomic"))
     {
         raceName = "read-atomic";
         access1  = "Read";
         access2  = "Atomic";
     }
     else if (QKeyValue.FindBoolAttribute(CallCex.FailingRequires.Attributes, "write_atomic"))
     {
         raceName = "write-atomic";
         access1  = "Write";
         access2  = "Atomic";
     }
     else
     {
         Debug.Assert(false);
         raceName = null;
         access1  = null;
         access2  = null;
     }
 }
Exemplo n.º 8
0
        private void ReportRace(CallCounterexample CallCex)
        {
            string raceName, access1, access2;

            DetermineNatureOfRace(CallCex, out raceName, out access1, out access2);

            PopulateModelWithStatesIfNecessary(CallCex);

            string RaceyArrayName = GetArrayName(CallCex.FailingRequires);

            Debug.Assert(RaceyArrayName != null);
            string RaceyArraySourceName = GetArraySourceName(CallCex.FailingRequires);

            Debug.Assert(RaceyArraySourceName != null);

            IEnumerable <SourceLocationInfo> PossibleSourcesForFirstAccess = GetPossibleSourceLocationsForFirstAccessInRace(CallCex, RaceyArrayName, AccessType.Create(access1),
                                                                                                                            GetStateName(CallCex));
            SourceLocationInfo SourceInfoForSecondAccess = new SourceLocationInfo(GetAttributes(CallCex.FailingCall), GetSourceFileName(), CallCex.FailingCall.tok);

            ErrorWriteLine("\n" + SourceInfoForSecondAccess.Top().GetFile() + ":", "possible " + raceName + " race on " +
                           ArrayOffsetString(CallCex, RaceyArraySourceName) +
                           ":\n", ErrorMsgType.Error);

            Console.Error.WriteLine(access2 + " by " + ThreadDetails(CallCex.Model, 2, true) + ", " + SourceInfoForSecondAccess.Top() + ":");
            SourceInfoForSecondAccess.PrintStackTrace();

            Console.Error.Write(access1 + " by " + ThreadDetails(CallCex.Model, 1, true) + ", ");
            if (PossibleSourcesForFirstAccess.Count() == 1)
            {
                Console.Error.WriteLine(PossibleSourcesForFirstAccess.ToList()[0].Top() + ":");
                PossibleSourcesForFirstAccess.ToList()[0].PrintStackTrace();
            }
            else if (PossibleSourcesForFirstAccess.Count() == 0)
            {
                Console.Error.WriteLine("from external source location\n");
            }
            else
            {
                Console.Error.WriteLine("possible sources are:");
                List <SourceLocationInfo> LocationsAsList = PossibleSourcesForFirstAccess.ToList();
                LocationsAsList.Sort(new SourceLocationInfo.SourceLocationInfoComparison());
                foreach (var sli in LocationsAsList)
                {
                    Console.Error.WriteLine(sli.Top() + ":");
                    sli.PrintStackTrace();
                }
                Console.Error.WriteLine();
            }
        }
Exemplo n.º 9
0
        public int ReportCounterexample(Counterexample error)
        {
            Contract.Requires(error != null);
            int errors = 0;

            if (error is AssertCounterexample)
            {
                AssertCounterexample cex = error as AssertCounterexample;

                if (QKeyValue.FindBoolAttribute(cex.FailingAssert.Attributes, "race_checking"))
                {
                    errors += this.ReportRace(cex);
                }
                else
                {
                    Console.WriteLine("Error: AssertCounterexample");
                    errors++;
                }
            }
            else if (error is CallCounterexample)
            {
                CallCounterexample cex = error as CallCounterexample;

                Console.WriteLine(cex.FailingRequires.Condition);
                Console.WriteLine(cex.FailingRequires.Line);
                Console.WriteLine("Error: CallCounterexample");
                this.ReportRequiresFailure(cex);
                errors++;
            }
            else if (error is ReturnCounterexample)
            {
                Console.WriteLine((error as ReturnCounterexample).FailingEnsures.Condition);
                Console.WriteLine((error as ReturnCounterexample).FailingEnsures.Line);
                Console.WriteLine("Error: ReturnCounterexample");
                errors++;
            }

            if (errors > 0)
            {
                this.FoundErrors = true;
            }

            return(errors);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Retrieves the race information.
        /// </summary>
        /// <param name="example">The counter example.</param>
        /// <param name="error">The race error.</param>
        /// <returns>The race errors.</returns>
        public IEnumerable <RaceError> GetRaceInformation(CallCounterexample example, RaceError error)
        {
            string raceName, access1, access2;

            DetermineNatureOfRace(example, out raceName, out access1, out access2);
            PopulateModelWithStatesIfNecessary(example);

            string raceyArrayName = GetArrayName(example.FailingRequires);
            IEnumerable <SourceLocationInfo> possibleSourcesForFirstAccess =
                GetPossibleSourceLocationsForFirstAccessInRace(
                    example, raceyArrayName, AccessType.Create(access1), GetStateName(example));
            SourceLocationInfo sourceInfoForSecondAccess = new SourceLocationInfo(
                GetAttributes(example.FailingCall), GetSourceFileName(), example.FailingCall.tok);

            error.RaceType = raceName;
            error.Access1  = access1;
            error.Access2  = access2;

            List <RaceError> errors = new List <RaceError>();

            foreach (SourceLocationInfo possibleSourceForFirstAccess in possibleSourcesForFirstAccess)
            {
                RaceError race = new RaceError(error.CounterExample, error.Implementation)
                {
                    RaceType = raceName,
                    Access1  = access1,
                    Access2  = access2,
                    Start    = possibleSourceForFirstAccess,
                    End      = sourceInfoForSecondAccess
                };

                errors.Add(race);
            }

            if (!errors.Any())
            {
                return new List <RaceError> {
                           error
                }
            }
            ;
            return(errors);
        }
Exemplo n.º 11
0
 private static AccessType GetAccessType(CallCounterexample err)
 {
     if (QKeyValue.FindBoolAttribute(err.FailingRequires.Attributes, "write_write") ||
         QKeyValue.FindBoolAttribute(err.FailingRequires.Attributes, "write_read") ||
         QKeyValue.FindBoolAttribute(err.FailingRequires.Attributes, "write_atomic"))
     {
         return(AccessType.WRITE);
     }
     else if (QKeyValue.FindBoolAttribute(err.FailingRequires.Attributes, "read_write") ||
              QKeyValue.FindBoolAttribute(err.FailingRequires.Attributes, "read_atomic"))
     {
         return(AccessType.READ);
     }
     else
     {
         Debug.Assert(QKeyValue.FindBoolAttribute(err.FailingRequires.Attributes, "atomic_read") ||
                      QKeyValue.FindBoolAttribute(err.FailingRequires.Attributes, "atomic_write"));
         return(AccessType.ATOMIC);
     }
 }
Exemplo n.º 12
0
        /// <summary>
        /// Generates the errors from the counter example.
        /// </summary>
        /// <param name="example">The counter example.</param>
        /// <param name="implementation">The implementation.</param>
        /// <returns>The error.</returns>
        private IEnumerable <Error> GenerateErrors(Counterexample example, Implementation implementation)
        {
            List <Error> errors = new List <Error>();

            if (example is CallCounterexample)
            {
                CallCounterexample callCounterexample = example as CallCounterexample;
                if (QKeyValue.FindBoolAttribute(callCounterexample.FailingRequires.Attributes, "barrier_divergence"))
                {
                    DivergenceError divergence = new DivergenceError(example, implementation);
                    ErrorReporter   reporter   = new ErrorReporter(program, implementation.Name);

                    reporter.PopulateDivergenceInformation(callCounterexample, divergence);
                    IdentifyVariables(divergence);

                    errors.Add(divergence);
                    return(errors);
                }
                else if (QKeyValue.FindBoolAttribute(callCounterexample.FailingRequires.Attributes, "race"))
                {
                    RaceError     template = new RaceError(example, implementation);
                    ErrorReporter reporter = new ErrorReporter(program, implementation.Name);

                    IEnumerable <RaceError> races = reporter.GetRaceInformation(callCounterexample, template);
                    foreach (RaceError race in races)
                    {
                        IdentifyVariables(race);
                    }

                    errors.AddRange(races);
                    return(errors);
                }
            }

            errors.Add(new Error(example, implementation));
            return(errors);
        }
Exemplo n.º 13
0
        internal void ReportCounterexample(Counterexample error)
        {
            int WindowWidth;

            try {
                WindowWidth = Console.WindowWidth;
            } catch (IOException) {
                WindowWidth = 20;
            }

            for (int i = 0; i < WindowWidth; i++)
            {
                Console.Error.Write("-");
            }

            if (error is CallCounterexample)
            {
                CallCounterexample CallCex = (CallCounterexample)error;
                if (QKeyValue.FindBoolAttribute(CallCex.FailingRequires.Attributes, "barrier_divergence"))
                {
                    ReportBarrierDivergence(CallCex.FailingCall);
                }
                else if (QKeyValue.FindBoolAttribute(CallCex.FailingRequires.Attributes, "race"))
                {
                    ReportRace(CallCex);
                }
                else
                {
                    ReportRequiresFailure(CallCex.FailingCall, CallCex.FailingRequires);
                }
            }
            else if (error is ReturnCounterexample)
            {
                ReturnCounterexample ReturnCex = (ReturnCounterexample)error;
                ReportEnsuresFailure(ReturnCex.FailingEnsures);
            }
            else
            {
                AssertCounterexample AssertCex = (AssertCounterexample)error;
                if (AssertCex.FailingAssert is LoopInitAssertCmd)
                {
                    ReportInvariantEntryFailure(AssertCex);
                }
                else if (AssertCex.FailingAssert is LoopInvMaintainedAssertCmd)
                {
                    ReportInvariantMaintedFailure(AssertCex);
                }
                else if (QKeyValue.FindBoolAttribute(AssertCex.FailingAssert.Attributes, "barrier_invariant"))
                {
                    ReportFailingBarrierInvariant(AssertCex);
                }
                else if (QKeyValue.FindBoolAttribute(AssertCex.FailingAssert.Attributes, "barrier_invariant_access_check"))
                {
                    ReportFailingBarrierInvariantAccessCheck(AssertCex);
                }
                else if (QKeyValue.FindBoolAttribute(AssertCex.FailingAssert.Attributes, "constant_write"))
                {
                    ReportFailingConstantWriteCheck(AssertCex);
                }
                else if (QKeyValue.FindBoolAttribute(AssertCex.FailingAssert.Attributes, "bad_pointer_access"))
                {
                    ReportFailingBadPointerAccess(AssertCex);
                }
                else if (QKeyValue.FindBoolAttribute(AssertCex.FailingAssert.Attributes, "array_bounds"))
                {
                    ReportFailingArrayBounds(AssertCex);
                }
                else
                {
                    ReportFailingAssert(AssertCex);
                }
            }

            DisplayParameterValues(error);

            if (((GVCommandLineOptions)CommandLineOptions.Clo).DisplayLoopAbstractions)
            {
                DisplayLoopAbstractions(error);
            }
        }
Exemplo n.º 14
0
        private IEnumerable <SourceLocationInfo> GetPossibleSourceLocationsForFirstAccessInRace(CallCounterexample CallCex, string ArrayName, AccessType AccessType, string RaceyState)
        {
            string AccessHasOccurred = RaceInstrumentationUtil.MakeHasOccurredVariableName(ArrayName, AccessType);
            string AccessOffset      = RaceInstrumentationUtil.MakeOffsetVariableName(ArrayName, AccessType);

            AssumeCmd ConflictingAction = DetermineConflictingAction(CallCex, RaceyState, AccessHasOccurred, AccessOffset);

            var ConflictingState = QKeyValue.FindStringAttribute(ConflictingAction.Attributes, "captureState");

            if (ConflictingState.Contains("loop_head_state"))
            {
                // The state may have been renamed (for example, if k-induction has been employed),
                // so we need to find the original state name.  This can be computed as the substring before the first
                // occurrence of '$'.  This inversion is fragile, and would be a good candidate for making robust
                string ConflictingStatePrefix;
                if (ConflictingState.Contains('$'))
                {
                    ConflictingStatePrefix = ConflictingState.Substring(0, ConflictingState.IndexOf('$'));
                }
                else
                {
                    ConflictingStatePrefix = ConflictingState;
                }
                Program originalProgram = GetOriginalProgram();
                var     blockGraph      = originalProgram.ProcessLoops(GetOriginalImplementation(originalProgram));
                Block   header          = FindLoopHeaderWithStateName(ConflictingStatePrefix, blockGraph);
                Debug.Assert(header != null);
                HashSet <Block> LoopNodes = new HashSet <Block>(
                    blockGraph.BackEdgeNodes(header).Select(Item => blockGraph.NaturalLoops(header, Item)).SelectMany(Item => Item)
                    );
                return(GetSourceLocationsFromBlocks("_CHECK_" + AccessType + "_" + ArrayName, LoopNodes));
            }
            else if (ConflictingState.Contains("call_return_state"))
            {
                return(GetSourceLocationsFromCall("_CHECK_" + AccessType + "_" + ArrayName,
                                                  QKeyValue.FindStringAttribute(ConflictingAction.Attributes, "procedureName")));
            }
            else
            {
                Debug.Assert(ConflictingState.Contains("check_state"));
                return(new HashSet <SourceLocationInfo> {
                    new SourceLocationInfo(ConflictingAction.Attributes, GetSourceFileName(), ConflictingAction.tok)
                });
            }
        }
Exemplo n.º 15
0
 private static string GetStateName(CallCounterexample CallCex)
 {
     return(GetStateName(CallCex.FailingCall.Attributes, CallCex));
 }