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());
            }
        }
Beispiel #2
0
        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());
            }
        }
Beispiel #4
0
        /// <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());
            }
        }
Beispiel #5
0
        /// <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);
                }
            }
        }
Beispiel #6
0
        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;
        }
Beispiel #7
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());
            }
        }
Beispiel #9
0
        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());
            }
        }
Beispiel #11
0
        /// <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());
            }
        }
Beispiel #12
0
        /// <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);
        }
Beispiel #13
0
        /// <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);
            }
        }
Beispiel #14
0
 private void ApplyInvariants()
 {
     if (this.Houdini != null)
     {
         Houdini.ApplyAssignment(this.SummarizedAC.BoogieProgram, this.Outcome);
         this.Houdini.Close();
         ToolCommandLineOptions.Get().TheProverFactory.Close();
     }
 }
Beispiel #15
0
        /// <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);
            }
        }
Beispiel #16
0
        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);
            }
        }
Beispiel #17
0
        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);
            }
        }
Beispiel #19
0
        /// <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);
        }
Beispiel #20
0
        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;
                }
            }
        }
Beispiel #21
0
        /// <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());
            }
        }
Beispiel #24
0
        /// <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());
            }
        }
Beispiel #25
0
        /// <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());
            }
        }
Beispiel #26
0
        /// <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);
                            }
                        }
                    }
                }
            }
        }
Beispiel #27
0
        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);
            }
        }
Beispiel #28
0
        /// <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());
            }
        }
Beispiel #29
0
        /// <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());
            }
        }
Beispiel #30
0
        /// <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);
                        }
                    }
                }
            }
        }