public void Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... ErrorReportingInstrumentation"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } foreach (var thread in this.AC.Threads) { this.Thread = thread; this.InstrumentAsyncFuncs(); this.CleanUp(); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
public void Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... ThreadRefactoring"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } foreach (var thread in this.AC.Threads) { this.ParseAndRenameNestedFunctions(thread, thread.Function, null); if (ToolCommandLineOptions.Get().SuperVerboseMode) { Output.PrintLine("..... Separated call graph of {0}", thread); } } this.CleanUp(); if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
public void Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... LoopInvariantInstrumentation"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } foreach (var thread in this.AC.Threads) { this.CandidateCounter.Add(thread, 0); this.InstrumentThread(thread); if (ToolCommandLineOptions.Get().SuperVerboseMode) { var suffix = this.CandidateCounter[thread] == 1 ? "" : "s"; Output.PrintLine("..... Instrumented '{0}' loop invariant candidate" + suffix + " in '{1}'", this.CandidateCounter[thread], thread.Name); } } this.InstrumentExistentialBooleans(); if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
/// <summary> /// Runs a lock abstraction pass. /// </summary> void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... LockUsageAnalysis"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } this.IdentifyLockCreationInThread(this.AC.MainThread); if (this.AC.Locks.Count > 0) { this.AlreadyAnalyzedImplementations.Clear(); this.IdentifyLockUsageInThread(this.AC.MainThread); } if (ToolCommandLineOptions.Get().SuperVerboseMode&& this.AC.Locks.Count == 0) { Output.PrintLine("..... No locks detected"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
/// <summary> /// Analyses the shared state of the given thread. /// </summary> /// <param name="thread">Thread</param> private void AnalyseThread(Thread thread) { this.AC.ThreadMemoryRegions.Add(thread, new HashSet <GlobalVariable>()); foreach (var impl in this.AC.GetThreadSpecificFunctions(thread)) { this.IdentifySharedMemoryRegions(thread, impl); } if (ToolCommandLineOptions.Get().SuperVerboseMode) { string accesses = ""; foreach (var mr in this.AC.ThreadMemoryRegions[thread]) { accesses += " '" + mr.Name + "'"; } if (this.AC.ThreadMemoryRegions[thread].Count == 0) { Output.PrintLine("..... {0} accesses no memory regions", thread, accesses); } else if (this.AC.ThreadMemoryRegions[thread].Count == 1) { Output.PrintLine("..... {0} accesses{1}", thread, accesses); } else { Output.PrintLine("..... {0} accesses{1}", thread, accesses); } } }
private void InstrumentThread(Thread thread) { this.Thread = thread; this.AddUpdateLocksetFunc(Microsoft.Boogie.Type.Int); foreach (var impl in this.AC.GetThreadSpecificFunctions(thread)) { this.InstrumentImplementation(impl); this.InstrumentProcedure(impl); } if (ToolCommandLineOptions.Get().SuperVerboseMode) { var p1 = this.LockCounter == 1 ? "" : "s"; var p2 = this.UnlockCounter == 1 ? "" : "s"; Output.PrintLine("..... Instrumented '{0}' lock" + p1 + " in {1}", this.LockCounter, thread); Output.PrintLine("..... Instrumented '{0}' unlock" + p2 + " in {1}", this.UnlockCounter, thread); } this.LockCounter = 0; this.UnlockCounter = 0; }
private void InstrumentThread(Thread thread) { this.Thread = thread; this.AddAccessFuncs(AccessType.WRITE); this.AddAccessFuncs(AccessType.READ); foreach (var impl in this.AC.GetThreadSpecificFunctions(thread)) { this.InstrumentImplementation(impl); this.InstrumentProcedure(impl); } if (ToolCommandLineOptions.Get().SuperVerboseMode) { var p1 = this.ReadCounter == 1 ? "" : "es"; var p2 = this.WriteCounter == 1 ? "" : "es"; Output.PrintLine("..... Instrumented '{0}' read access" + p1 + " in {1}", this.ReadCounter, thread.Name); Output.PrintLine("..... Instrumented '{0}' write access" + p2 + " in {1}", this.WriteCounter, thread.Name); } this.ReadCounter = 0; this.WriteCounter = 0; }
void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... GlobalRaceCheckingInstrumentation"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } foreach (var thread in this.AC.Threads) { this.AddCurrentLocksets(thread); this.AddMemoryLocksets(thread); this.AddAccessCheckingVariables(thread); if (ToolCommandLineOptions.Get().SuperVerboseMode) { Output.PrintLine("..... Instrumented lockset analysis globals for {0}", thread); } } this.AddAccessWatchdogConstants(); if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... LocksetInstrumentation"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } this.InstrumentMainFunction(); this.AddNonCheckedFunc(); foreach (var thread in this.AC.Threads) { this.InstrumentThread(thread); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... SharedStateAbstraction"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } foreach (var impl in this.AC.TopLevelDeclarations.OfType <Implementation>().ToList()) { this.AbstractReadAccesses(impl); this.AbstractWriteAccesses(impl); // this.CleanUpModset(impl); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
/// <summary> /// Runs a thread usage analysis pass. /// </summary> void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... ThreadUsageAnalysis"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } this.CreateMainThread(); this.IdentifyThreadUsageInThread(this.AC.MainThread); if (ToolCommandLineOptions.Get().SuperVerboseMode&& this.AC.Threads.Count == 0) { Output.PrintLine("..... No child threads detected"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
/// <summary> /// Abstracts and returns the spawned thread. /// </summary> /// <param name="parent">Parent</param> /// <param name="impl">Implementation</param> /// <param name="tidExpr">Expr</param> /// <param name="spawner">CallCmd</param> private Thread GetAbstractSpawnedThread(Thread parent, Implementation impl, Expr tidExpr, CallCmd spawner) { ThreadId tid = this.GetAbstractThreadId(tidExpr, impl, spawner); string threadName = ""; if (spawner.Ins[2] is IdentifierExpr) { threadName = (spawner.Ins[2] as IdentifierExpr).Name; } else if (spawner.Ins[2] is NAryExpr) { var threadExpr = spawner.Ins[2] as NAryExpr; if (threadExpr.Fun.FunctionName.StartsWith("$bitcast.")) { threadName = (threadExpr.Args[0] as IdentifierExpr).Name; } } var thread = Thread.Create(this.AC, tid, threadName, spawner.Ins[3], parent); parent.AddChild(thread); if (ToolCommandLineOptions.Get().SuperVerboseMode) { Output.PrintLine("..... {0} spawns {1}", parent, thread); } return(thread); }
/// <summary> /// Creates main thread. /// </summary> private void CreateMainThread() { var thread = Thread.CreateMain(this.AC); if (ToolCommandLineOptions.Get().SuperVerboseMode) { Output.PrintLine("..... {0} is the main thread", thread); } }
private void ApplyInvariants() { if (this.Houdini != null) { Houdini.ApplyAssignment(this.SummarizedAC.BoogieProgram, this.Outcome); this.Houdini.Close(); ToolCommandLineOptions.Get().TheProverFactory.Close(); } }
/// <summary> /// Abstracts the blocked thread. /// </summary> /// <param name="parent">Parent</param> /// <param name="impl">Implementation</param> /// <param name="tidExpr">Expr</param> /// <param name="spawner">CallCmd</param> private void AbstractBlockedThread(Thread parent, Implementation impl, Expr tidExpr, CallCmd spawner) { ThreadId tid = this.GetAbstractThreadId(tidExpr, impl, spawner); if (ToolCommandLineOptions.Get().SuperVerboseMode) { Output.PrintLine("..... {0} blocks unidentified thread with id '{1}'", parent, tid.Id); } }
private void PerformHoudini() { var houdiniStats = new HoudiniSession.HoudiniStatistics(); GC.Collect(); try { this.Houdini = new Houdini(this.AC.BoogieProgram, houdiniStats); this.Outcome = this.Houdini.PerformHoudiniInference(); } catch (OutOfMemoryException) { Lockpwn.IO.Reporter.WarningWriteLine("Warning: Houdini run out of memory"); GC.Collect(); throw new AnalysisFailedException(); } catch (Exception ex) { Lockpwn.IO.Reporter.WarningWriteLine("Warning: Houdini failed: " + ex.Message); GC.Collect(); throw new AnalysisFailedException(); } if (CommandLineOptions.Clo.PrintAssignment) { Output.PrintLine("..... Assignment computed by Houdini:"); foreach (var x in this.Outcome.assignment) { Output.PrintLine(x.Key + " = " + x.Value); } } if (ToolCommandLineOptions.Get().SuperVerboseMode) { int numTrueAssigns = 0; foreach (var x in this.Outcome.assignment) { if (x.Value) { numTrueAssigns++; } } Output.PrintLine("..... Number of true assignments = " + numTrueAssigns); Output.PrintLine("..... Number of false assignments = " + (this.Outcome.assignment.Count - numTrueAssigns)); Output.PrintLine("..... Prover time = " + houdiniStats.proverTime.ToString("F2")); Output.PrintLine("..... Unsat core prover time = " + houdiniStats.unsatCoreProverTime.ToString("F2")); Output.PrintLine("..... Number of prover queries = " + houdiniStats.numProverQueries); Output.PrintLine("..... Number of unsat core prover queries = " + houdiniStats.numUnsatCoreProverQueries); Output.PrintLine("..... Number of unsat core prunings = " + houdiniStats.numUnsatCorePrunings); } }
void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... YieldInstrumentation"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } this.InstrumentYieldInThreadCreate(); this.InstrumentYieldInCallWrapperStart(); this.InstrumentYieldInThreadStart(); foreach (var impl in this.AC.TopLevelDeclarations.OfType <Implementation>().ToList()) { if (this.AC.IsAToolFunc(impl.Name)) { continue; } if (Utilities.ShouldNotAccessFunction(impl.Name)) { continue; } if (Utilities.ShouldSkipFromAnalysis(impl.Name)) { continue; } this.InstrumentYieldInThreadJoins(impl); this.InstrumentYieldInLocks(impl); this.InstrumentYieldInUnlocks(impl); this.InstrumentYieldInMemoryAccesses(impl); } if (ToolCommandLineOptions.Get().SuperVerboseMode) { var suffix = this.YieldCounter == 1 ? "" : "s"; Output.PrintLine("..... Instrumented '{0}' yield" + suffix + "", this.YieldCounter); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
private void InstrumentExistentialBooleans() { if (this.ExistentialBooleans.Count == 0) { return; } ToolCommandLineOptions.Get().RequiresInvariantInference = true; foreach (var b in this.ExistentialBooleans) { b.Attributes = new QKeyValue(Token.NoToken, "existential", new List <object>() { Expr.True }, null); this.AC.TopLevelDeclarations.Add(b); } }
/// <summary> /// Abstracts the used lock. /// </summary> /// <param name="parent">Parent</param> /// <param name="lockExpr">Expr</param> /// <param name="locker">CallCmd</param> private void AbstractUsedLock(Thread parent, Expr lockExpr, CallCmd locker) { Lock l = this.GetAbstractLock(lockExpr); if (ToolCommandLineOptions.Get().SuperVerboseMode) { Output.PrintLine("..... {0} uses unidentified lock '{1}'", parent, l.Name); } if (Output.Debugging) { Output.PrintLine("....... replacing lock '{0}' in call '{1}', line {2}", locker.Ins[0], locker.callee, locker.Line); } locker.Ins[0] = new IdentifierExpr(l.Id.tok, l.Id); }
private void SimplifyImplementation(Implementation impl) { foreach (var block in impl.Blocks) { if (ToolCommandLineOptions.Get().EnableCorralMode || ToolCommandLineOptions.Get().DisableUserAssertions) { block.Cmds.RemoveAll(val => val is AssertCmd); } this.RemoveDomainSpecificFunctions(block); foreach (var call in block.cmds.OfType <CallCmd>().Where(val => val.IsAsync)) { call.IsAsync = false; } } }
/// <summary> /// Runs a race checking analysis pass. /// </summary> void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... RaceCheckAnalysis"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } this.CheckForRaces(); if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
/// <summary> /// Emites to a user specified file. /// </summary> /// <param name="declarations">Declarations</param> internal static void EmitToUserSpecifiedFile(List <Declaration> declarations) { string directory = ToolCommandLineOptions.Get().OutputDirectory; var fileName = ""; if (directory.Length > 0) { BoogieProgramEmitter.TryCreateDirectory(directory); fileName = directory + Path.DirectorySeparatorChar + ToolCommandLineOptions.Get().OutputFile; } else { fileName = ToolCommandLineOptions.Get().OutputFile; } using (TokenTextWriter writer = new TokenTextWriter(fileName, true)) { declarations.Emit(writer); } }
void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... AccessCheckingInstrumentation"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } this.InstrumentMain(); if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
/// <summary> /// Runs a Houdini invariant inference analysis pass. /// </summary> void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... InvariantInference-Houdini"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } this.PerformHoudini(); this.ApplyInvariants(); if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
/// <summary> /// Runs an atomic regions usage pass. /// </summary> void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... AtomicRegionsAnalysis"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } foreach (var impl in this.AC.TopLevelDeclarations.OfType <Implementation>().ToList()) { this.IdentifyUseOfAtomicsInImplementation(impl); if (this.UsesAtomicLock && !ToolCommandLineOptions.Get().SuperVerboseMode) { break; } } if (this.UsesAtomicLock) { this.CreateAtomicLock(); } if (ToolCommandLineOptions.Get().SuperVerboseMode&& !this.UsesAtomicLock) { Output.PrintLine("..... No use of atomics detected"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
/// <summary> /// Performs an analysis to identify use of atomics. /// </summary> /// <param name="impl">Implementation</param> private void IdentifyUseOfAtomicsInImplementation(Implementation impl) { foreach (var block in impl.Blocks) { foreach (var cmd in block.Cmds) { if (cmd is CallCmd) { CallCmd call = cmd as CallCmd; if (call.callee.Equals("corral_atomic_begin") || call.callee.Equals("corral_atomic_end")) { this.UsesAtomicLock = true; if (ToolCommandLineOptions.Get().SuperVerboseMode) { Output.PrintLine("..... {0} uses atomic lock 'lock$atomic'", impl.Name); } } } } } }
private void PerformHoudini() { var houdiniStats = new HoudiniSession.HoudiniStatistics(); this.Houdini = new Houdini(this.AC.BoogieProgram, houdiniStats); this.Outcome = this.Houdini.PerformHoudiniInference(); if (CommandLineOptions.Clo.PrintAssignment) { Output.PrintLine("..... Assignment computed by Houdini:"); foreach (var x in this.Outcome.assignment) { Output.PrintLine(x.Key + " = " + x.Value); } } if (ToolCommandLineOptions.Get().SuperVerboseMode) { int numTrueAssigns = 0; foreach (var x in this.Outcome.assignment) { if (x.Value) { numTrueAssigns++; } } Output.PrintLine("..... Number of true assignments = " + numTrueAssigns); Output.PrintLine("..... Number of false assignments = " + (this.Outcome.assignment.Count - numTrueAssigns)); Output.PrintLine("..... Prover time = " + houdiniStats.proverTime.ToString("F2")); Output.PrintLine("..... Unsat core prover time = " + houdiniStats.unsatCoreProverTime.ToString("F2")); Output.PrintLine("..... Number of prover queries = " + houdiniStats.numProverQueries); Output.PrintLine("..... Number of unsat core prover queries = " + houdiniStats.numUnsatCoreProverQueries); Output.PrintLine("..... Number of unsat core prunings = " + houdiniStats.numUnsatCorePrunings); } }
/// <summary> /// Runs a program simplification pass. /// </summary> void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... ProgramSimplifier"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } foreach (var impl in this.AC.TopLevelDeclarations.OfType <Implementation>().ToList()) { this.SimplifyImplementation(impl); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
/// <summary> /// Runs a shared state analysis pass. /// </summary> void IPass.Run() { if (ToolCommandLineOptions.Get().VerboseMode) { Output.PrintLine("... SharedStateAnalysis"); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer = new ExecutionTimer(); this.Timer.Start(); } foreach (var thread in this.AC.Threads) { this.AnalyseThread(thread); } if (ToolCommandLineOptions.Get().MeasureTime) { this.Timer.Stop(); Output.PrintLine("..... [{0}]", this.Timer.Result()); } }
/// <summary> /// Performs an analysis to identify lock usage. /// </summary> /// <param name="parent">Thread</param> /// <param name="impl">Implementation</param> /// <param name="ins">Optional list of expressions</param> private void IdentifyLockUsageInImplementation(Thread parent, Implementation impl, List <Expr> inPtrs = null) { if (this.AlreadyAnalyzedImplementations.Contains(impl)) { return; } this.AlreadyAnalyzedImplementations.Add(impl); foreach (var block in impl.Blocks) { foreach (var cmd in block.Cmds) { if (cmd is CallCmd) { CallCmd call = cmd as CallCmd; if (call.callee.Equals("pthread_mutex_lock") || call.callee.Equals("pthread_mutex_unlock")) { var exprs = new HashSet <Expr>(); var result = new PointerAnalysis(this.AC, impl).GetPointerOrigins(call.Ins[0], out exprs); var lockExpr = exprs.FirstOrDefault(); if (result != PointerAnalysis.ResultType.Allocated && result != PointerAnalysis.ResultType.Shared && inPtrs != null) { lockExpr = new PointerAnalysis(this.AC, impl).RecomputeExprFromInParams(lockExpr, inPtrs); } bool matched = false; foreach (var l in this.AC.Locks) { if (l.IsEqual(this.AC, impl, lockExpr)) { if (ToolCommandLineOptions.Get().SuperVerboseMode) { Output.PrintLine("..... {0} uses lock '{1}'", parent, l.Name); } if (Output.Debugging) { Output.PrintLine("....... replacing lock '{0}' in call '{1}', line {2}", call.Ins[0], call.callee, call.Line); } call.Ins[0] = new IdentifierExpr(l.Id.tok, l.Id); matched = true; break; } } if (!matched && this.AC.Locks.Count == 1) { var l = this.AC.Locks[0]; if (ToolCommandLineOptions.Get().SuperVerboseMode) { Output.PrintLine("..... {0} uses lock '{1}'", parent, l.Name); } if (Output.Debugging) { Output.PrintLine("....... replacing lock '{0}' in call '{1}', line {2}", call.Ins[0], call.callee, call.Line); } call.Ins[0] = new IdentifierExpr(l.Id.tok, l.Id); } else if (!matched) { this.AbstractUsedLock(parent, lockExpr, call); } } if (!Utilities.ShouldSkipFromAnalysis(call.callee) || call.callee.StartsWith("pthread_create$") || call.callee.StartsWith("__call_wrapper$")) { List <Expr> computedRootPointers = new List <Expr>(); foreach (var inParam in call.Ins) { if (inParam is NAryExpr) { computedRootPointers.Add(inParam); } else { var exprs = new HashSet <Expr>(); new PointerAnalysis(this.AC, impl).GetPointerOrigins(inParam, out exprs); var ptrExpr = exprs.FirstOrDefault(); computedRootPointers.Add(ptrExpr); } } Thread child = null; if (call.callee.StartsWith("pthread_create$")) { var tid = computedRootPointers[0] as IdentifierExpr; child = this.AC.Threads.First(val => !val.IsMain && val.Id.IsEqual(tid)); parent = child; } this.IdentifyLockUsageInCall(parent, call, computedRootPointers); } } } } }