private Dictionary <string, AssumeCmd> GetConflictingAccesses(AssertCounterexample cex, string resource) { var assumes = new Dictionary <string, AssumeCmd>(); foreach (var block in cex.Trace) { foreach (var assume in block.Cmds.OfType <AssumeCmd>()) { var sharedResource = this.GetSharedResourceName(assume.Attributes); if (sharedResource == null || !sharedResource.Equals(resource)) { continue; } var access = this.GetAccessType(assume.Attributes); if (access == null) { continue; } var state = this.GetAccessStateName(assume.Attributes); if (!assumes.ContainsKey(state)) { assumes.Add(state, assume); } } } return(assumes); }
private int ReportRace(AssertCounterexample cex) { this.PopulateModelWithStatesIfNecessary(cex); var resource = this.GetSharedResourceName(cex.FailingAssert.Attributes); var conflictingActions = this.GetConflictingAccesses(cex, resource); this.UnprotectedResources.Add(resource); if (WhoopCommandLineOptions.Get().DebugWhoop) { Console.WriteLine("Conflict in resource: " + resource); } if (WhoopCommandLineOptions.Get().ShowErrorModel) { this.Write(cex.Model, conflictingActions); } int errorCounter = 0; foreach (var action1 in conflictingActions) { foreach (var action2 in conflictingActions) { if (this.AnalyseConflict(action1.Key, action2.Key, action1.Value, action2.Value)) { errorCounter++; } } } return(errorCounter == 0 ? 1 : errorCounter); }
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 { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("..... Error: AssertCounterexample"); } errors++; } } if (errors > 0) { this.FoundErrors = true; } return(errors); }
//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(); } } }
private static void ReportThreadSpecificFailure(AssertCounterexample err, string messagePrefix) { AssertCmd failingAssert = err.FailingAssert; Console.Error.WriteLine(); var sli = new SourceLocationInfo(GetAttributes(failingAssert), GetSourceFileName(), failingAssert.tok); int relevantThread = QKeyValue.FindIntAttribute(GetAttributes(failingAssert), "thread", -1); Debug.Assert(relevantThread == 1 || relevantThread == 2); ErrorWriteLine(sli.Top() + ":", messagePrefix + " for " + ThreadDetails(err.Model, relevantThread, true), ErrorMsgType.Error); sli.PrintStackTrace(); Console.Error.WriteLine(); }
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); }
private void ReportFailingArrayBounds(AssertCounterexample err) { PopulateModelWithStatesIfNecessary(err); string state = GetStateName(err); string arrayName = QKeyValue.FindStringAttribute(err.FailingAssert.Attributes, "array_name"); Model.Number ArrayOffset = GetStateFromModel(state, err.Model).TryGet("_ARRAY_OFFSET_" + arrayName) as Model.Number; Axiom arrayInfo = GetOriginalProgram().Axioms.Where(Item => QKeyValue.FindStringAttribute(Item.Attributes, "array_info") == arrayName).ElementAt(0); string arrayAccess = GetArrayAccess(ParseOffset(ArrayOffset), QKeyValue.FindStringAttribute(arrayInfo.Attributes, "source_name"), Convert.ToUInt32(QKeyValue.FindIntAttribute(arrayInfo.Attributes, "elem_width", -1)), Convert.ToUInt32(QKeyValue.FindIntAttribute(arrayInfo.Attributes, "source_elem_width", -1)), QKeyValue.FindStringAttribute(arrayInfo.Attributes, "source_dimensions").Split(',')); var sli = new SourceLocationInfo(GetAttributes(err.FailingAssert), GetSourceFileName(), err.FailingAssert.tok); ErrorWriteLine(sli.Top() + ":", "possible array out-of-bounds access on array " + arrayAccess + " by " + ThreadDetails(err.Model, 2, false) + ":", ErrorMsgType.Error); sli.PrintStackTrace(); Console.Error.WriteLine(); }
private static void ReportFailingBadPointerAccess(AssertCounterexample err) { ReportThreadSpecificFailure(err, "possible null pointer access"); }
public static Counterexample ReconstructTrace(Counterexample trace, string currProc, TraceLocation currLocation, Dictionary <string, Tuple <Block, Implementation> > origProg) { // we cannot be starting in the last block Debug.Assert(currLocation.numBlock != trace.Trace.Count - 1); // we cannot be starting in the middle of a block Debug.Assert(currLocation.numInstr == 0); var newTrace = new List <Block>(); var newTraceCallees = new Dictionary <TraceLocation, CalleeCounterexampleInfo>(); Block currOrigBlock = null; Implementation currOrigImpl = null; int currOrigInstr = 0; while (true) { if (currLocation.numInstr == 0 && origProg.ContainsKey(trace.Trace[currLocation.numBlock].Label)) { var origPlace = origProg[trace.Trace[currLocation.numBlock].Label]; if (currOrigImpl != null && currOrigImpl.Name != origPlace.Item2.Name) { // change of proc // First, recurse var calleeTrace = ReconstructTrace(trace, origPlace.Item2.Name, currLocation, origProg); // Find the call to this guy in currOrigBlock while (currOrigInstr < currOrigBlock.Cmds.Count) { var cmd = currOrigBlock.Cmds[currOrigInstr] as CallCmd; if (cmd != null && cmd.callee == origPlace.Item2.Name) { break; } currOrigInstr++; } Debug.Assert(currOrigInstr != currOrigBlock.Cmds.Count); newTraceCallees.Add(new TraceLocation(newTrace.Count - 1, currOrigInstr), new CalleeCounterexampleInfo(calleeTrace, new List <object>())); // we're done break; } currOrigBlock = origPlace.Item1; currOrigImpl = origProg[trace.Trace[currLocation.numBlock].Label].Item2; currOrigInstr = 0; newTrace.Add(currOrigBlock); } if (trace.calleeCounterexamples.ContainsKey(currLocation)) { // find the corresponding call in origBlock var calleeInfo = trace.calleeCounterexamples[currLocation]; var calleeName = trace.getCalledProcName(trace.Trace[currLocation.numBlock].Cmds[currLocation.numInstr]); while (currOrigInstr < currOrigBlock.Cmds.Count) { var cmd = currOrigBlock.Cmds[currOrigInstr] as CallCmd; if (cmd != null && cmd.callee == calleeName) { break; } currOrigInstr++; } Debug.Assert(currOrigInstr != currOrigBlock.Cmds.Count); newTraceCallees.Add(new TraceLocation(newTrace.Count - 1, currOrigInstr), calleeInfo); } // increment location currLocation.numInstr++; if (currLocation.numInstr >= trace.Trace[currLocation.numBlock].Cmds.Count) { currLocation.numBlock++; currLocation.numInstr = 0; } if (currLocation.numBlock == trace.Trace.Count) { break; } } var ret = new AssertCounterexample(newTrace, null, null, trace.Model, trace.MvInfo, trace.Context); ret.calleeCounterexamples = newTraceCallees; return(ret); }
public BoogieAssertErrorTrace(AssertCounterexample c, Implementation m, Program p) : base(c, m, p) { acex = c; }
private static void ReportFailingAssert(AssertCounterexample err) { ReportThreadSpecificFailure(err, "this assertion might not hold"); }
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); } }
private static string GetStateName(AssertCounterexample AssertCex) { return(GetStateName(AssertCex.FailingAssert.Attributes, AssertCex)); }
private static void ReportFailingConstantWriteCheck(AssertCounterexample err) { ReportThreadSpecificFailure(err, "possible attempt to modify constant memory"); }
private static void ReportFailingBarrierInvariantAccessCheck(AssertCounterexample err) { ReportThreadSpecificFailure(err, "insufficient permission may be held for evaluation of this barrier invariant"); }
private static void ReportFailingBarrierInvariant(AssertCounterexample err) { ReportThreadSpecificFailure(err, "this barrier invariant might not hold"); }
private static void ReportInvariantEntryFailure(AssertCounterexample err) { ReportThreadSpecificFailure(err, "loop invariant might not hold on entry"); }
private static void ReportInvariantMaintedFailure(AssertCounterexample err) { ReportThreadSpecificFailure(err, "loop invariant might not be maintained by the loop"); }