Beispiel #1
0
        /// <summary>
        /// If type is an interface, returns all concrete implementing classes
        /// else if type is an abstract class, returns all concrete extending classes
        /// </summary>
        /// <param name="psd"></param>
        /// <param name="type"></param>
        /// <param name="extendingClasses"></param>
        /// <returns></returns>
        public static bool TryGetExtendingClasses(PexMeStaticDatabase psd, TypeEx type, out IIndexable <TypeDefinition> extendingClasses)
        {
            //load inheritance hierarchies if not already done
            psd.LoadInheritanceHierarchies();
            extendingClasses = null;

            TypeStore ts;

            if (!psd.TypeDictionary.TryGetValue(type.Definition, out ts))
            {
                return(false);
            }

            SafeSet <TypeDefinition> extendingClassesSet = new SafeSet <TypeDefinition>();

            CollectAllExtendingClasses(ts, extendingClassesSet);

            if (extendingClassesSet.Count == 0)
            {
                return(false);
            }

            var extendingClassesList = new SafeList <TypeDefinition>();

            foreach (var tdef in extendingClassesSet)
            {
                extendingClassesList.Add(tdef);
            }

            extendingClasses = extendingClassesList;
            return(true);
        }
Beispiel #2
0
        public Connection(IMessageBus newMessageBus,
                          IJsonSerializer jsonSerializer,
                          string baseSignal,
                          string connectionId,
                          IEnumerable<string> signals,
                          IEnumerable<string> groups,
                          ITraceManager traceManager,
                          IAckHandler ackHandler,
                          IPerformanceCounterWriter performanceCounterWriter)
        {
            _bus = newMessageBus;
            _serializer = jsonSerializer;
            _baseSignal = baseSignal;
            _connectionId = connectionId;
            _signals = new HashSet<string>(signals);
            _groups = new SafeSet<string>(groups);
            _traceSource = new Lazy<TraceSource>(() => traceManager["SignalR.Connection"]);
            _ackHandler = ackHandler;

            var counters = performanceCounterWriter;
            _msgsRecTotalCounter = counters.GetCounter(PerformanceCounters.ConnectionMessagesReceivedTotal);
            _msgsRecPerSecCounter = counters.GetCounter(PerformanceCounters.ConnectionMessagesReceivedPerSec);
            _msgsSentTotalCounter = counters.GetCounter(PerformanceCounters.ConnectionMessagesSentTotal);
            _msgsSentPerSecCounter = counters.GetCounter(PerformanceCounters.ConnectionMessagesSentPerSec);
        }
        /// <summary>
        /// Function that retrieves associated method store 
        /// </summary>
        /// <param name="pms"></param>
        /// <param name="ms"></param>
        /// <returns></returns>
        public static bool TryGetFieldStore(IPexComponent host, PersistentFieldStore pfs, out FieldStore fs)
        {
            fs = new FieldStore();

            bool bresult = MethodOrFieldAnalyzer.TryGetFieldFromPersistentStringForm(host, pfs.FieldName, out fs.FieldName);
            SafeDebug.Assume(bresult, "Failed to get field from the persistent store");

            fs.FieldValues.AddRange(pfs.FieldValues);

            //TODO: Performance can be improved via caching over here
            foreach (var mname in pfs.ReadMethods)
            {
                Method m;
                bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, mname, out m);
                SafeDebug.Assume(bresult, "Failed to get method from persistent string form ");
                fs.ReadMethods.Add(m);
            }

            foreach (var typeex in pfs.WriteMethods.Keys)
            {
                SafeSet<Method> wmethods = new SafeSet<Method>();
                TypeEx typeEx;
                bresult = MethodOrFieldAnalyzer.TryGetTypeExFromPersistentStringForm(host, typeex, out typeEx);
                SafeDebug.Assume(bresult, "Failed to get type from persistent string form " + typeex);

                fs.WriteMethods.Add(typeEx, wmethods);

                HashSet<string> methods;
                bresult = pfs.WriteMethods.TryGetValue(typeex, out methods);
                SafeDebug.Assume(bresult, "Failed to get associated set of methods for a type " + typeex);

                foreach (var m in methods)
                {
                    Method method;
                    bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, m, out method);
                    SafeDebug.Assume(bresult, "Failed to get method from string form " + m);
                    wmethods.Add(method);
                }
            }

            foreach (var m in pfs.ModificationTypeDictionary.Keys)
            {
                var value = pfs.ModificationTypeDictionary[m];
                Method method;
                bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, m, out method);
                SafeDebug.Assume(bresult, "Failed to get method from string form " + m);
                fs.ModificationTypeDictionary.Add(method, value);
            }

            foreach (var m in pfs.PreciseModificationTypeDictionary.Keys)
            {
                var value = pfs.PreciseModificationTypeDictionary[m];
                Method method;
                bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, m, out method);
                SafeDebug.Assume(bresult, "Failed to get method from string form " + m);
                fs.PreciseModificationTypeDictionary.Add(method, value);
            }

            return true;
        }
        /// <summary>
        /// Removes if there are any infeasible definitions
        /// </summary>
        private void RemoveInfeasibleDefs(DUCoverStore dcs)
        {
            //There are either zero or one definitions
            if (this.defDic.Count <= 1)
            {
                return;
            }

            SafeSet <FieldDefUseStore> infeasibleDefs = new SafeSet <FieldDefUseStore>();

            foreach (var fdef in this.defDic.Keys)
            {
                var otherFDefOffsets = this.GetOtherDefOffsetsInMethod(fdef.Method, fdef);
                if (otherFDefOffsets.Count == 0)
                {
                    continue;
                }

                if (HasRedefinition(dcs, fdef, otherFDefOffsets))
                {
                    infeasibleDefs.Add(fdef);
                }
            }
            this.defDic.RemoveRange(infeasibleDefs);
        }
Beispiel #5
0
        public Connection(IMessageBus newMessageBus,
                          IJsonSerializer jsonSerializer,
                          string baseSignal,
                          string connectionId,
                          IEnumerable <string> signals,
                          IEnumerable <string> groups,
                          ITraceManager traceManager,
                          IAckHandler ackHandler,
                          IPerformanceCounterWriter performanceCounterWriter)
        {
            _bus          = newMessageBus;
            _serializer   = jsonSerializer;
            _baseSignal   = baseSignal;
            _connectionId = connectionId;
            _signals      = new HashSet <string>(signals);
            _groups       = new SafeSet <string>(groups);
            _traceSource  = new Lazy <TraceSource>(() => traceManager["SignalR.Connection"]);
            _ackHandler   = ackHandler;

            var counters = performanceCounterWriter;

            _msgsRecTotalCounter   = counters.GetCounter(PerformanceCounters.ConnectionMessagesReceivedTotal);
            _msgsRecPerSecCounter  = counters.GetCounter(PerformanceCounters.ConnectionMessagesReceivedPerSec);
            _msgsSentTotalCounter  = counters.GetCounter(PerformanceCounters.ConnectionMessagesSentTotal);
            _msgsSentPerSecCounter = counters.GetCounter(PerformanceCounters.ConnectionMessagesSentPerSec);
        }
        /// <summary>
        /// Given a uncovered code location and the associated terms, this
        /// method infers factory method for that code location.
        ///
        /// Assumes that the uncovered branch is mainly due to an object creating issue
        /// </summary>
        /// <returns></returns>
        public bool TryInferFactoryMethod(UncoveredCodeLocationStore ucls, out SafeSet <Method> suggestedMethods)
        {
            SafeDebug.AssumeNotNull(ucls, "ucls");

            if (ucls.AllFields.Count == 0)
            {
                this.host.Log.LogError(WikiTopics.MissingWikiTopic, "factoryguesser",
                                       "No information about involving fields in the uncovered branch");
                suggestedMethods = null;
                return(false);
            }

            //Check whether the feature is currently supported
            FieldModificationType fmt = this.GetRequiredFieldModificationType(ucls);

            if (!(fmt == FieldModificationType.NON_NULL_SET ||
                  fmt == FieldModificationType.NULL_SET || fmt == FieldModificationType.INCREMENT || fmt == FieldModificationType.DECREMENT ||
                  fmt == FieldModificationType.FALSE_SET || fmt == FieldModificationType.TRUE_SET))
            {
                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                         "Format " + fmt.ToString() + " is not supported for suggesting factory methods");
                suggestedMethods = null;
                return(false);
            }

            //Step 1: Get the exact type whose factory method is required for covering this branch.
            //Decided based on where there is a subsequent field which can be directly handled rather than the top field.
            //This step is moved to the place where the uncovered location is initially stored

            //Step 2: Decide which methods of this type should be invoked. Use a bottomup approach
            //for inferrinfg the exact method
            if (!this.GetTargetMethod(ucls, ucls.TargetField, out suggestedMethods))
            {
                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                         "Failed to retrieve the target method of field " + ucls.TargetField.FullName + " in type " + ucls.ExplorableType.FullName);
                suggestedMethods = null;
                return(false);
            }

            var sb = new StringBuilder();

            foreach (var m in suggestedMethods)
            {
                sb.AppendLine(MethodOrFieldAnalyzer.GetMethodSignature(m));
            }
            ucls.SuggestedMethodsforFactory = sb.ToString();

            //Create a factory suggestion store. This is expected by the rest of the code.
            FactorySuggestionStore fss;

            if (!this.pmd.FactorySuggestionsDictionary.TryGetValue(ucls.ExplorableType.ToString(), out fss))
            {
                fss = new FactorySuggestionStore();
                fss.DeclaringType = ucls.ExplorableType.ToString();
                this.pmd.FactorySuggestionsDictionary[ucls.ExplorableType.ToString()] = fss;
            }

            return(true);
        }
        /// <summary>
        /// Function that retrieves associated method store 
        /// </summary>
        /// <param name="pms"></param>
        /// <param name="ms"></param>
        /// <returns></returns>
        public static bool TryGetMethodStore(IPexComponent host, PersistentMethodStore pms, out MethodStore ms)
        {
            ms = new MethodStore();

            bool bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, pms.methodName, out ms.methodName);
            SafeDebug.Assume(bresult, "Failed to get the method from persistent form " + pms.methodName);

            foreach (var fieldstr in pms.ReadFields)
            {
                Field field;
                bresult = MethodOrFieldAnalyzer.TryGetFieldFromPersistentStringForm(host, fieldstr, out field);
                SafeDebug.Assume(bresult, "Failed to get the field from persistent form " + fieldstr);
                ms.ReadFields.Add(field);
            }

            foreach (var fieldstr in pms.WriteFields)
            {
                Field field;
                bresult = MethodOrFieldAnalyzer.TryGetFieldFromPersistentStringForm(host, fieldstr, out field);
                SafeDebug.Assume(bresult, "Failed to get the field from persistent form " + fieldstr);
                ms.WriteFields.Add(field);
            }

            foreach (var typeexstr in pms.CallingMethods.Keys)
            {
                SafeSet<Method> wmethods = new SafeSet<Method>();
                TypeEx typeEx;
                bresult = MethodOrFieldAnalyzer.TryGetTypeExFromPersistentStringForm(host, typeexstr, out typeEx);
                if (!bresult)
                {
                    //No strict safedebugging cannot be added for calling methods since there
                    //can be several dummy methods from Pex side
                    continue;
                }

                ms.CallingMethods.Add(typeEx, wmethods);

                var methods = pms.CallingMethods[typeexstr];
                foreach (var mstr in methods)
                {
                    Method method;
                    bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, mstr, out method);
                    if (!bresult)
                        continue;
                    wmethods.Add(method);
                }
            }

            foreach (var calledMethodStr in pms.CalledMethods)
            {
                Method method;
                bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, calledMethodStr, out method);
                if (!bresult)
                    continue;
                ms.CalledMethods.Add(method);
            }

            return true;
        }
Beispiel #8
0
 public DiffSet(IEnumerable <T> items)
 {
     _reset        = true;
     _addedItems   = new HashSet <T>(items);
     _removedItems = new HashSet <T>();
     // We don't want to re-enumerate items
     _items = new SafeSet <T>(_addedItems);
 }
        /// <summary>
        /// Populates all pair-wise combinations of defs and uses identified through static analysis
        /// </summary>
        public void PopulateDUCoverTable()
        {
            DUCoverStore dcs = DUCoverStore.GetInstance();

            SafeSet <FieldDefUseStore> allDefs = new SafeSet <FieldDefUseStore>();

            allDefs.AddRange(this.DefDic.Keys);
            allDefs.AddRange(this.DefOrUseSet);

            SafeSet <FieldDefUseStore> allUses = new SafeSet <FieldDefUseStore>();

            allUses.AddRange(this.UseDic.Keys);
            allUses.AddRange(this.DefOrUseSet);
            int numInfeasible = 0;

            //Compute pair-wise combinations
            foreach (var defEntry in allDefs)
            {
                foreach (var useEntry in allUses)
                {
                    //Ignore the trivial entries that involve just a combination of setter and getter methods
                    if (defEntry.Method.ShortName.StartsWith("set_") && useEntry.Method.ShortName.StartsWith("get_"))
                    {
                        continue;
                    }
                    if (!this.IsFeasibleDUCoverEntry(dcs, defEntry, useEntry))
                    {
                        numInfeasible++;
                        continue;
                    }

                    DUCoverStoreEntry dcse = new DUCoverStoreEntry(this.fd, defEntry.Method, defEntry.Offset,
                                                                   useEntry.Method, useEntry.Offset);

                    if (defEntry.UnknownSideEffectMethod != null)
                    {
                        dcse.Def_UnknownSideEffectMethod = defEntry.UnknownSideEffectMethod;
                        dcse.DefUnsure = true;
                    }

                    if (useEntry.UnknownSideEffectMethod != null)
                    {
                        dcse.Use_UnknownSideEffectMethod = useEntry.UnknownSideEffectMethod;
                        dcse.UseUnsure = true;
                    }

                    if (!this.duCoverageTable.ContainsKey(dcse))
                    {
                        this.duCoverageTable[dcse] = 0;
                    }
                }
            }

            //Clear all the cached entries.
            this.feasibilityDicCache.Clear();

            logger.Debug("Detected infeasible du-pairs for field " + this.fd.FullName + "(" + numInfeasible + ")");
        }
        /// <summary>
        /// Includes filtering of the methods based on desired format
        /// </summary>
        /// <returns></returns>
        public bool TryGetFilteredWriteMethods(Field field, TypeEx declaringType, FieldModificationType desiredfmt, out SafeSet <Method> writeMethods)
        {
            //Check in the predefined store before proceeding
            if (PreDefinedMethodEffects.TryGetWriteMethods(this, field, desiredfmt, out writeMethods))
            {
                SafeSet <Method> newWriteMethods = new SafeSet <Method>();
                GetCallingMethods(field, declaringType, writeMethods, newWriteMethods);

                //Filter those methods whose actual types are abstract
                SafeSet <Method> returnMethods = new SafeSet <Method>();
                foreach (Method m in writeMethods)
                {
                    TypeEx declType;
                    if (m.TryGetDeclaringType(out declType) && !declType.IsAbstract && !declType.IsInterface)
                    {
                        returnMethods.Add(m);
                    }
                }

                foreach (Method m in newWriteMethods)
                {
                    TypeEx declType;
                    if (m.TryGetDeclaringType(out declType) && !declType.IsAbstract && !declType.IsInterface)
                    {
                        returnMethods.Add(m);
                    }
                }

                writeMethods.Clear();
                writeMethods.AddRange(returnMethods);
                return(true);
            }

            //Identify those method that directly modify this field
            if (!TryGetWriteMethods(field, declaringType, out writeMethods))
            {
                return(false);
            }

            //C# supports properties. In that case, the property setter can also
            //be a viable method. add property setter and its callers also
            Property property;

            if (MethodOrFieldAnalyzer.TryGetPropertyModifyingField(this, declaringType, field, out property))
            {
                if (property.IsVisible(VisibilityContext.Exported))
                {
                    writeMethods.Add(property.Setter);
                }

                var newWriteMethods = new SafeSet <Method>();
                GetCallingMethods(field, declaringType, writeMethods, newWriteMethods);
                writeMethods.AddRange(newWriteMethods);
            }

            writeMethods = FilterWriteMethodsOfUpdateType(field, desiredfmt, writeMethods);
            return(true);
        }
        protected override void AfterRun(IPexPathComponent host, object data)
        {
            Term[]               pathConditions  = new Term[] {};
            IList <Term>         conditions      = null;
            IList <CodeLocation> locations       = null;
            SafeSet <Method>     trackingMethods = null;

            var database = host.GetService <IssueTrackDatabase>();
            var unInstrumentedMethods = database.UnInstrumentedMethods;

            log = database.SimpleLog;
            foreach (var unInstrumentedMethod in unInstrumentedMethods)
            {
                var controller = new ResultTracer(host, unInstrumentedMethod.Method, log);
                log.AppendLine("try tracking " + unInstrumentedMethod.Method.FullName);
                log.AppendLine("*****************************************************");
                using (IEngine trackingEngine = host.PathServices.TrackingEngineFactory.CreateTrackingEngine(controller))
                {
                    trackingEngine.GetService <IPexTrackingDriver>().Run();
                    pathConditions  = Enumerable.ToArray(controller.PathConditions);
                    conditions      = controller.Conditions;
                    locations       = controller.Locations;
                    trackingMethods = controller.TrackingMethods;
                }
                PexLog(host, "ResultTracing", prettyPrintPathCondition(host, pathConditions));
//                log.AppendLine("condition: " + prettyPrintPathCondition(host, pathConditions));
                PexLog(host, "tracking methods", trackingMethods.Select(x => x.FullName));
                for (int i = 0; i < conditions.Count; i++)
                {
                    var condition = conditions[i];
                    using (var extractor = new ResultTrackConditionExtractor(host.ExplorationServices.TermManager))
                    {
                        extractor.VisitTerm(default(TVoid), condition);
                        if (extractor.Method == null)
                        {
                            host.Log.Dump("method", "not in branch", "null");
                            continue;
                        }
                        PexLog(host, "method", extractor.Method.FullName);

                        PexLog(host, "offset", extractor.CallerOffset.ToString("x"));
                        PexLog(host, "location", extractor.Location.ToString());
                        var method = extractor.Signature as Method;
                        PexLog(host, "signature", method.FullName);
                        log.AppendLine("found method: " + method.FullName + " in branch " + locations[i]);
                        if (!host.GetService <IssueTrackDatabase>().UninstrumentedMethodInBranch.ContainsKey(locations[i]))
                        {
                            host.GetService <IssueTrackDatabase>().UninstrumentedMethodInBranch.Add(locations[i], method);
                        }
                    }
                }

                PexLog(host, "location", locations.Select(x => x.ToString()));
                log.AppendLine("*****************************************************");
            }
            log.AppendLine("=========================");
        }
Beispiel #12
0
 /// <summary>
 /// Generates nested command files. Ignores if there are any PUTs in
 /// pmd.PendingExplorationMethods since those methods can cause cycles.
 /// </summary>
 /// <param name="allSuggestedNewPUTs"></param>
 /// <param name="cmdfile"></param>
 private void GenerateNestedCommandFile(SafeSet <Method> allSuggestedNewPUTs, string cmdfile)
 {
     using (StreamWriter sw = new StreamWriter(cmdfile))
     {
         foreach (var newput in allSuggestedNewPUTs)
         {
             var newputsig = MethodOrFieldAnalyzer.GetMethodSignature(newput);
             sw.WriteLine(PUTGenerator.PUTGenerator.GeneratePUTCommand(newput));
         }
     }
 }
Beispiel #13
0
        /// <summary>
        /// Filters out covered code locations
        /// </summary>
        public void FilterOutCoveredCodeLocations()
        {
            //Finding out covered locations
            //Also Finding out other locations in system libraries
            //that do not contribute to increase in the covered. Those
            //libraries should also be removed
            var coveredLocations = new SafeSet <UncoveredCodeLocationStoreList>();

            foreach (var uclStoreList in this.UncoveredLocationDictionary.Values)
            {
                var cl = uclStoreList.Location;
                if (this.IsBranchOffsetCoveredInMethod(cl.Method, cl.Offset))
                {
                    coveredLocations.Add(uclStoreList);
                }
                else
                {
                    //Check whether the uncoverd location is in system library
                    var  currAssembly  = this.Services.CurrentAssembly.Assembly.Assembly;
                    bool bDeleteUCList = true;

                    foreach (var ucstore in uclStoreList.StoreList)
                    {
                        //Check the CUTMethodCall sequence in the ucstore to decide
                        //whether to continue with this
                        foreach (var method in ucstore.CUTMethodCallSequence)
                        {
                            var methoddef = method.Definition;
                            if (methoddef.Module.Assembly == currAssembly && !this.AreAllOffsetsCoveredInMethod(method))
                            {
                                bDeleteUCList = false;
                                break;
                            }
                        }

                        if (!bDeleteUCList)
                        {
                            break;
                        }
                    }

                    if (bDeleteUCList)
                    {
                        coveredLocations.Add(uclStoreList);
                    }
                }
            }

            foreach (var covered in coveredLocations)
            {
                var key = UncoveredCodeLocationStore.GetKey(covered.Location.ToString(), covered.ExplorableType, covered.TermIndex);
                this.UncoveredLocationDictionary.Remove(key);
            }
        }
Beispiel #14
0
        /// <summary>
        /// Generates a put for an uncovered DUCoverStoreEntry
        /// </summary>
        /// <param name="dcse"></param>
        public void GeneratePUT(DUCoverStoreEntry dcse)
        {
            //Check whether the TypeEx of field, and both the methods is same. If not raise warning
            TypeEx fieldTypeEx;

            if (!dcse.Field.TryGetDeclaringType(out fieldTypeEx))
            {
                logger.Warn("Failed to get the declaring type of the field " + dcse.Field.FullName);
                return;
            }

            TypeEx defMethodEx;

            if (!dcse.DefMethod.TryGetDeclaringType(out defMethodEx))
            {
                logger.Warn("Failed to get the declaring type of the method " + dcse.DefMethod.FullName);
                return;
            }

            TypeEx useMethodEx;

            if (!dcse.UseMethod.TryGetDeclaringType(out useMethodEx))
            {
                logger.Warn("Failed to get the declaring type of the method " + dcse.UseMethod.FullName);
                return;
            }

            if (!fieldTypeEx.Equals(defMethodEx) || !defMethodEx.Equals(useMethodEx))
            {
                logger.Warn("All declaring types of field, def-method, and use-method should be same for generating PUT. Condition failed for " + dcse.ToString());
                return;
            }

            try
            {
                string putgenerated = "";

                SafeSet <string> existingPUTs;
                if (!this.PUTDictionary.TryGetValue(fieldTypeEx.FullName, out existingPUTs))
                {
                    existingPUTs = new SafeSet <string>();
                    this.PUTDictionary[fieldTypeEx.FullName] = existingPUTs;
                }

                existingPUTs.Add(putgenerated);
            }
            catch (Exception ex)
            {
                logger.ErrorException("Failed to generate PUT for " + dcse.ToString() + " " + ex.Message, ex);
            }
        }
Beispiel #15
0
 public Connection(IMessageBus messageBus,
                   IJsonSerializer jsonSerializer,
                   string baseSignal,
                   string connectionId,
                   IEnumerable<string> signals,
                   IEnumerable<string> groups,
                   ITraceManager traceManager)
 {
     _messageBus = messageBus;
     _serializer = jsonSerializer;
     _baseSignal = baseSignal;
     _connectionId = connectionId;
     _signals = new HashSet<string>(signals);
     _groups = new SafeSet<string>(groups);
     _trace = traceManager;
 }
Beispiel #16
0
 public Connection(INewMessageBus newMessageBus,
                   IJsonSerializer jsonSerializer,
                   string baseSignal,
                   string connectionId,
                   IEnumerable <string> signals,
                   IEnumerable <string> groups,
                   ITraceManager traceManager)
 {
     _bus          = newMessageBus;
     _serializer   = jsonSerializer;
     _baseSignal   = baseSignal;
     _connectionId = connectionId;
     _signals      = new HashSet <string>(signals);
     _groups       = new SafeSet <string>(groups);
     _traceSource  = new Lazy <TraceSource>(() => traceManager["SignalR.Connection"]);
 }
Beispiel #17
0
 public Connection(INewMessageBus newMessageBus,
                   IJsonSerializer jsonSerializer,
                   string baseSignal,
                   string connectionId,
                   IEnumerable<string> signals,
                   IEnumerable<string> groups,
                   ITraceManager traceManager)
 {
     _bus = newMessageBus;
     _serializer = jsonSerializer;
     _baseSignal = baseSignal;
     _connectionId = connectionId;
     _signals = new HashSet<string>(signals);
     _groups = new SafeSet<string>(groups);
     _traceSource = new Lazy<TraceSource>(() => traceManager["SignalR.Connection"]);
 }
Beispiel #18
0
 public Connection(IMessageBus messageBus,
                   IJsonSerializer jsonSerializer,
                   string baseSignal,
                   string connectionId,
                   IEnumerable <string> signals,
                   IEnumerable <string> groups,
                   ITraceManager traceManager)
 {
     _messageBus   = messageBus;
     _serializer   = jsonSerializer;
     _baseSignal   = baseSignal;
     _connectionId = connectionId;
     _signals      = new HashSet <string>(signals);
     _groups       = new SafeSet <string>(groups);
     _trace        = traceManager;
 }
Beispiel #19
0
        /// <summary>
        /// recursively collects all extending classes
        /// </summary>
        /// <param name="ts"></param>
        private static void CollectAllExtendingClasses(TypeStore ts, SafeSet <TypeDefinition> extendingClasses)
        {
            if (extendingClasses.Contains(ts.Type))
            {
                return;
            }

            foreach (var innerts in ts.ExtendingTypes)
            {
                if (!innerts.Type.IsAbstract && !innerts.Type.IsInterface)
                {
                    extendingClasses.Add(innerts.Type);
                }

                CollectAllExtendingClasses(innerts, extendingClasses);
            }
        }
Beispiel #20
0
        protected double EvaluateArithmeticModel(ref IArithmeticModel model)
        {
            double distance     = 0.0;
            double fitnessValue = 0.0;

            Term           innerTerm;
            SafeSet <Term> visited = new SafeSet <Term>();

            this.fitnessEvaluations++;

            foreach (var variable in this.context.Variables)
            {
                foreach (var constraint in variable.Constraints)
                {
                    if (!visited.Add(constraint))
                    {
                        continue;
                    }

                    if (this.termManager.TryGetInnerLogicallyNegatedValue(constraint, out innerTerm))
                    {
                        distance = EvaluateConstraint(ref model, innerTerm, true);
                    }
                    else
                    {
                        distance = EvaluateConstraint(ref model, constraint, false);
                    }

                    if (distance == Double.MaxValue)
                    {
                        fitnessValue = distance;
                        break;
                    }
                    else
                    {
                        fitnessValue += distance;
                    }
                }
            }

            visited.ClearAndTrim();
            visited = null;

            return(fitnessValue);
        }
        private void GetCallingMethods(Field field, TypeEx declaringType, SafeSet <Method> writeMethods, SafeSet <Method> newWriteMethods)
        {
            foreach (var writeM in writeMethods)
            {
                if (writeM.Definition.DeclaredVisibility != Visibility.Private || writeM.IsConstructor)
                {
                    newWriteMethods.Add(writeM);
                    continue;
                }

                //Get other calling methods within this type
                SafeSet <Method> localCM;
                if (this.TryGetCallingMethodsInType(writeM, field, declaringType, out localCM))
                {
                    newWriteMethods.AddRange(localCM);
                }
            }
        }
        internal SafeSet <Method> FilterCallingMethodsBasedOnField(Method tmw, Field field,
                                                                   SafeSet <Method> callingMethods)
        {
            SafeSet <Method> filteredMethods = new SafeSet <Method>();

            foreach (var callingm in callingMethods)
            {
                //Filter the calling method based on the field
                MethodBodyEx body;
                if (!callingm.TryGetBody(out body) || !body.HasInstructions)
                {
                    continue;
                }

                int         offset = 0;
                Instruction instruction;
                bool        bContinueWithNextMethod = false;
                Field       lastAccessedField       = null;
                while (body.TryGetInstruction(offset, out instruction) && !bContinueWithNextMethod)
                {
                    SafeDebug.AssumeNotNull(instruction, "instruction");
                    OpCode opCode = instruction.OpCode;
                    if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldflda)
                    {
                        SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                        lastAccessedField = instruction.Field;
                    }
                    else if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt)
                    {
                        SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod, "opCode.OperandType == OperandType.InlineMethod");
                        Method methodinner = instruction.Method;

                        if (methodinner == tmw && field == lastAccessedField)
                        {
                            filteredMethods.Add(callingm);
                            bContinueWithNextMethod = true;
                        }
                        lastAccessedField = null;
                    }
                    offset = instruction.NextOffset;
                }
            }
            return(filteredMethods);
        }
        protected internal Task Save(Message message)
        {
            var key = message.SignalKey;
            SafeSet<Message> list;
            if (!_items.TryGetValue(key, out list)) {
                list = new SafeSet<Message>();
                _items.TryAdd(key, list);
            }
            list.Add(message);
            if (message.Id > _messageId) {
                lock (_idLocker) {
                    if (message.Id > _messageId) {
                        _messageId = message.Id;
                    }
                }
            }

            return TaskAsyncHelper.Empty;
        }
Beispiel #24
0
 public Connection(IMessageBus newMessageBus,
                   IJsonSerializer jsonSerializer,
                   string baseSignal,
                   string connectionId,
                   IEnumerable <string> signals,
                   IEnumerable <string> groups,
                   ITraceManager traceManager,
                   IAckHandler ackHandler,
                   IPerformanceCounterManager performanceCounterManager)
 {
     _bus          = newMessageBus;
     _serializer   = jsonSerializer;
     _baseSignal   = baseSignal;
     _connectionId = connectionId;
     _signals      = new HashSet <string>(signals, StringComparer.OrdinalIgnoreCase);
     _groups       = new SafeSet <string>(groups);
     _traceSource  = new Lazy <TraceSource>(() => traceManager["SignalR.Connection"]);
     _ackHandler   = ackHandler;
     _counters     = performanceCounterManager;
 }
Beispiel #25
0
 public Connection(IMessageBus newMessageBus,
                   IJsonSerializer jsonSerializer,
                   string baseSignal,
                   string connectionId,
                   IEnumerable<string> signals,
                   IEnumerable<string> groups,
                   ITraceManager traceManager,
                   IAckHandler ackHandler,
                   IPerformanceCounterManager performanceCounterManager)
 {
     _bus = newMessageBus;
     _serializer = jsonSerializer;
     _baseSignal = baseSignal;
     _connectionId = connectionId;
     _signals = new HashSet<string>(signals, StringComparer.OrdinalIgnoreCase);
     _groups = new SafeSet<string>(groups);
     _traceSource = new Lazy<TraceSource>(() => traceManager["SignalR.Connection"]);
     _ackHandler = ackHandler;
     _counters = performanceCounterManager;
 }
        /// <summary>
        /// Retrieves the write methods for a field, if exists from the predefined settings.
        /// </summary>
        public static bool TryGetWriteMethods(IPexComponent host, Field field, FieldModificationType desiredFmt, 
            out SafeSet<Method> writeMethods)
        {
            if (!isPredefinedEffectsParsed)
                ParsePredefinedEffects(host);

            PreDefinedMethodEffectsStore pdme = new PreDefinedMethodEffectsStore(field, desiredFmt);
            PreDefinedMethodEffectsStore existingPdme;
            if (effectsStore.TryGetValue(pdme, out existingPdme))
            {
                writeMethods = new SafeSet<Method>();
                writeMethods.AddRange(existingPdme.suggestedmethodList);
                return true;
            }
            else
            {
                writeMethods = null;
                return false;
            }
        }
Beispiel #27
0
        /// <summary>
        /// Makes a mapping relationship between a calling method and a called method
        /// </summary>
        /// <param name="callingMethod"></param>
        /// <param name="calledMethod"></param>
        public void AddMethodMapping(Method callingMethod, Method calledMethod)
        {
            //Updating the method store for calling methods
            MethodStore callingMethodStore = null;

            if (!methodDic.TryGetValue(callingMethod, out callingMethodStore))
            {
                callingMethodStore            = new MethodStore();
                callingMethodStore.methodName = calledMethod;
                methodDic[callingMethod]      = callingMethodStore;
            }
            callingMethodStore.CalledMethods.Add(calledMethod);

            //Updating the method store for called methods
            MethodStore calledMethodStore = null;

            if (!methodDic.TryGetValue(calledMethod, out calledMethodStore))
            {
                calledMethodStore            = new MethodStore();
                calledMethodStore.methodName = calledMethod;
                methodDic[calledMethod]      = calledMethodStore;
            }

            TypeEx callingMethodType;

            if (!callingMethod.TryGetDeclaringType(out callingMethodType))
            {
                this.Log.LogError(WikiTopics.MissingWikiTopic, "methodmapping",
                                  "Failed to get the declared type for method " + calledMethod);
                return;
            }

            SafeSet <Method> localCallingMethods;

            if (!calledMethodStore.CallingMethods.TryGetValue(callingMethodType, out localCallingMethods))
            {
                localCallingMethods = new SafeSet <Method>();
                calledMethodStore.CallingMethods[callingMethodType] = localCallingMethods;
            }
            localCallingMethods.Add(callingMethod);
        }
        /// <summary>
        /// Given a set of write methods, this method basically filters them out
        /// to create a new set. Also filters the method that belongs to the interface type
        /// </summary>
        /// <param name="field"></param>
        /// <param name="fieldModificationType"></param>
        /// <param name="writeMethods"></param>
        /// <returns></returns>
        private SafeSet <Method> FilterWriteMethodsOfUpdateType(Field field,
                                                                FieldModificationType fieldModificationType, SafeSet <Method> writeMethods)
        {
            FieldStore fs;

            if (!this.FieldDictionary.TryGetValue(field, out fs))
            {
                return(writeMethods);
            }

            SafeSet <Method> returnSet = new SafeSet <Method>();

            foreach (var method in writeMethods)
            {
                //no need of methods in interfaces or abstract classes.
                TypeEx declType;
                if (method.TryGetDeclaringType(out declType) && (declType.IsAbstract || declType.IsInterface))
                {
                    continue;
                }

                //We currently allow unknown types
                FieldModificationType fmt;

                //Problem of static analysis impreciseness. If no modificuatui
                if (!fs.ModificationTypeDictionary.TryGetValue(method, out fmt))
                {
                    returnSet.Add(method);
                }

                if (fmt == fieldModificationType || fmt == FieldModificationType.UNKNOWN || fmt == FieldModificationType.METHOD_CALL)
                {
                    returnSet.Add(method);
                }
            }

            return(returnSet);
        }
        /// <summary>
        /// Retrieves the write methods for a field, if exists from the predefined settings.
        /// </summary>
        public static bool TryGetWriteMethods(IPexComponent host, Field field, FieldModificationType desiredFmt,
                                              out SafeSet <Method> writeMethods)
        {
            if (!isPredefinedEffectsParsed)
            {
                ParsePredefinedEffects(host);
            }

            PreDefinedMethodEffectsStore pdme = new PreDefinedMethodEffectsStore(field, desiredFmt);
            PreDefinedMethodEffectsStore existingPdme;

            if (effectsStore.TryGetValue(pdme, out existingPdme))
            {
                writeMethods = new SafeSet <Method>();
                writeMethods.AddRange(existingPdme.suggestedmethodList);
                return(true);
            }
            else
            {
                writeMethods = null;
                return(false);
            }
        }
Beispiel #30
0
        /// <summary>
        /// Function that retrieves associated method store
        /// </summary>
        /// <param name="pms"></param>
        /// <param name="ms"></param>
        /// <returns></returns>
        public static bool TryGetMethodStore(IPexComponent host, PersistentMethodStore pms, out MethodStore ms)
        {
            ms = new MethodStore();

            bool bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, pms.methodName, out ms.methodName);

            SafeDebug.Assume(bresult, "Failed to get the method from persistent form " + pms.methodName);

            foreach (var fieldstr in pms.ReadFields)
            {
                Field field;
                bresult = MethodOrFieldAnalyzer.TryGetFieldFromPersistentStringForm(host, fieldstr, out field);
                SafeDebug.Assume(bresult, "Failed to get the field from persistent form " + fieldstr);
                ms.ReadFields.Add(field);
            }

            foreach (var fieldstr in pms.WriteFields)
            {
                Field field;
                bresult = MethodOrFieldAnalyzer.TryGetFieldFromPersistentStringForm(host, fieldstr, out field);
                SafeDebug.Assume(bresult, "Failed to get the field from persistent form " + fieldstr);
                ms.WriteFields.Add(field);
            }

            foreach (var typeexstr in pms.CallingMethods.Keys)
            {
                SafeSet <Method> wmethods = new SafeSet <Method>();
                TypeEx           typeEx;
                bresult = MethodOrFieldAnalyzer.TryGetTypeExFromPersistentStringForm(host, typeexstr, out typeEx);
                if (!bresult)
                {
                    //No strict safedebugging cannot be added for calling methods since there
                    //can be several dummy methods from Pex side
                    continue;
                }

                ms.CallingMethods.Add(typeEx, wmethods);

                var methods = pms.CallingMethods[typeexstr];
                foreach (var mstr in methods)
                {
                    Method method;
                    bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, mstr, out method);
                    if (!bresult)
                    {
                        continue;
                    }
                    wmethods.Add(method);
                }
            }

            foreach (var calledMethodStr in pms.CalledMethods)
            {
                Method method;
                bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, calledMethodStr, out method);
                if (!bresult)
                {
                    continue;
                }
                ms.CalledMethods.Add(method);
            }

            return(true);
        }
        private void GetCallingMethods(Field field, TypeEx declaringType, SafeSet<Method> writeMethods, SafeSet<Method> newWriteMethods)
        {
            foreach (var writeM in writeMethods)
            {
                if (writeM.Definition.DeclaredVisibility != Visibility.Private || writeM.IsConstructor)
                {
                    newWriteMethods.Add(writeM);
                    continue;
                }

                //Get other calling methods within this type
                SafeSet<Method> localCM;
                if (this.TryGetCallingMethodsInType(writeM, field, declaringType, out localCM))
                {
                    newWriteMethods.AddRange(localCM);
                }
            }
        }
Beispiel #32
0
        /// <summary>
        /// recursively collects all extending classes
        /// </summary>
        /// <param name="ts"></param>
        private static void CollectAllExtendingClasses(TypeStore ts, SafeSet<TypeDefinition> extendingClasses)
        {
            if (extendingClasses.Contains(ts.Type))
                return;

            foreach (var innerts in ts.ExtendingTypes)
            {
                if (!innerts.Type.IsAbstract && !innerts.Type.IsInterface)
                    extendingClasses.Add(innerts.Type);

                CollectAllExtendingClasses(innerts, extendingClasses);
            }
        }
        /// <summary>
        /// Computes method effects statically. All written fields of a method.
        /// Can be imprecise and conservative
        /// </summary>
        /// <param name="declaringType"></param>
        /// <param name="method"></param>
        /// <param name="effects"></param>
        /// <returns></returns>
        public static bool TryComputeMethodEffects(IPexComponent host, TypeEx declaringType, Method method,
                                                   SafeSet <Method> visitedMethods, out MethodEffects effects)
        {
            SafeDebug.AssumeNotNull(declaringType, "declaringType");
            SafeDebug.AssumeNotNull(method, "method");

            try
            {
                if (visitedMethods == null)
                {
                    visitedMethods = new SafeSet <Method>();
                }

                if (visitedMethods.Contains(method))
                {
                    effects = null;
                    return(false);
                }

                visitedMethods.Add(method);

                //Check whether this has been computed before
                var psd = host.GetService <IPexMeStaticDatabase>() as PexMeStaticDatabase;
                if (psd.MethodEffectsDic.TryGetValue(method.GlobalIndex, out effects))
                {
                    return(true);
                }

                var res                 = new SafeSet <string>();
                var directSetFields     = new SafeSet <string>();
                var directCalledMethods = new SafeSet <Method>();
                var returnFields        = new SafeSet <Field>();
                var modificationTypeDic = new SafeDictionary <string, FieldModificationType>();
                var parameters          = method.Parameters;

                MethodBodyEx body;
                if (!method.TryGetBody(out body) || !body.HasInstructions)
                {
                    effects = null;
                    return(false);
                }

                int         callDepth = 0;
                int         offset    = 0;
                Instruction instruction;
                OpCode      prevOpcode = OpCodes.Nop;

                //Stack for load instructions
                Field lastAccessedArrayField = null;
                Field lastAccessedField      = null;

                while (body.TryGetInstruction(offset, out instruction))
                {
                    SafeDebug.AssumeNotNull(instruction, "instruction");
                    OpCode opCode = instruction.OpCode;
                    if (LdcOpCodes.Contains(opCode))
                    {
                        //topIsConstant = true;
                    }
                    else if (ConvOpCodes.Contains(opCode))
                    {
                        // do not change topIsConstant
                    }
                    else
                    {
                        if (opCode == OpCodes.Stfld)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                            Field field = instruction.Field;
                            AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, field, field.Type);
                        }
                        else if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldflda)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                            Field accessedField = instruction.Field;

                            if (accessedField.Type.Spec == TypeSpec.SzArray)
                            {
                                lastAccessedArrayField = accessedField;
                            }
                            else
                            {
                                lastAccessedField = accessedField;
                            }
                        }
                        else if (StElemOpCodes.Contains(opCode))
                        {
                            if (lastAccessedArrayField != null)
                            {
                                //Indicates that there is n array type modified
                                AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, lastAccessedArrayField, lastAccessedArrayField.Type);
                                lastAccessedArrayField = null;
                            }
                        }
                        else if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod, "opCode.OperandType == OperandType.InlineMethod");
                            Method methodinner = instruction.Method;
                            SafeDebug.AssumeNotNull(method, "method");

                            directCalledMethods.Add(methodinner);
                            TypeEx methodDeclaringType;

                            //are these function calls are within the parent types
                            if (methodinner.TryGetDeclaringType(out methodDeclaringType) &&
                                declaringType.IsAssignableTo(methodDeclaringType))
                            {
                                MethodEffects methodEffects;
                                if (TryComputeMethodEffects(host, methodDeclaringType, methodinner, visitedMethods, out methodEffects))
                                {
                                    res.AddRange(methodEffects.WrittenInstanceFields);
                                    foreach (var key in methodEffects.ModificationTypeDictionary.Keys)
                                    {
                                        modificationTypeDic[key] = methodEffects.ModificationTypeDictionary[key];
                                    }
                                    directSetFields.AddRange(methodEffects.DirectSetterFields);
                                    if (methodEffects.CallDepth > callDepth)
                                    {
                                        callDepth = methodEffects.CallDepth;
                                    }
                                }
                            }
                            else
                            {
                                //introducing heuristics for inter-procedural static analysis
                                if (lastAccessedField != null && lastAccessedField.Type.IsReferenceType &&
                                    !(methodinner.ShortName.StartsWith("Get") || methodinner.ShortName.StartsWith("get") ||
                                      methodinner.ShortName.StartsWith("Set") || methodinner.ShortName.StartsWith("set")))
                                {
                                    AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic,
                                                            prevOpcode, lastAccessedField, lastAccessedField.Type);
                                }
                            }
                        }
                        else if (opCode == OpCodes.Ret)
                        {
                            if (instruction.Field != null)
                            {
                                returnFields.Add(instruction.Field);
                            }
                        }
                        //topIsConstant = false;
                    }

                    prevOpcode = opCode;
                    offset     = instruction.NextOffset;
                }

                effects = new MethodEffects((IFiniteSet <string>)res, directSetFields, directCalledMethods, returnFields, modificationTypeDic, callDepth + 1);
                psd.MethodEffectsDic[method.GlobalIndex] = effects;
                return(true);
            }
            catch (Exception ex)
            {
                host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "methodeffects",
                                               "Failed to compute method effects for method " + method.FullName + "," + ex.Message);
                effects = null;
                return(false);
            }
        }
        /// <summary>
        /// Given a set of write methods, this method basically filters them out
        /// to create a new set. Also filters the method that belongs to the interface type
        /// </summary>
        /// <param name="field"></param>
        /// <param name="fieldModificationType"></param>
        /// <param name="writeMethods"></param>
        /// <returns></returns>
        private SafeSet<Method> FilterWriteMethodsOfUpdateType(Field field,
            FieldModificationType fieldModificationType, SafeSet<Method> writeMethods)
        {
            FieldStore fs;
            if (!this.FieldDictionary.TryGetValue(field, out fs))
                return writeMethods;

            SafeSet<Method> returnSet = new SafeSet<Method>();
            foreach (var method in writeMethods)
            {
                //no need of methods in interfaces or abstract classes.
                TypeEx declType;
                if (method.TryGetDeclaringType(out declType) && (declType.IsAbstract || declType.IsInterface))
                {
                    continue;
                }

                //We currently allow unknown types
                FieldModificationType fmt;

                //Problem of static analysis impreciseness. If no modificuatui
                if (!fs.ModificationTypeDictionary.TryGetValue(method, out fmt))
                    returnSet.Add(method);

                if (fmt == fieldModificationType || fmt == FieldModificationType.UNKNOWN || fmt == FieldModificationType.METHOD_CALL)
                    returnSet.Add(method);
            }

            return returnSet;
        }
Beispiel #35
0
 public ProxyObservable()
 {
     _observers = new SafeSet <Needle <IObserver <T> > >();
 }
        private static TypeEx AddFieldToMethodEffects(IPexComponent host, TypeEx declaringType, SafeSet<Field> res,
            SafeSet<Field> directSetFields,
            SafeDictionary<Field, FieldModificationType> modificationTypeDic,
            OpCode prevOpcode, Field field, TypeEx fieldType)
        {
            SafeDebug.AssumeNotNull(field, "field");
            SafeDebug.Assume(!field.IsStatic, "!field.IsStatic");

            TypeEx fieldDeclaringType;
            //The following check ensures that the field belongs to this class
            //or its base classes
            if (field.TryGetDeclaringType(out fieldDeclaringType) &&
                declaringType.IsAssignableTo(fieldDeclaringType))
            {
                res.Add(field);

                var fieldTypeStr = fieldType.ToString();
                if (fieldTypeStr == "System.Int32" || fieldTypeStr == "System.Int64" || fieldTypeStr == "System.Int16")
                {
                    if (prevOpcode == OpCodes.Add)
                        modificationTypeDic[field] = FieldModificationType.INCREMENT;
                    else if (prevOpcode == OpCodes.Sub)
                        modificationTypeDic[field] = FieldModificationType.DECREMENT;
                    else
                        host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                            "Encountered unknown modification type for integer type " + prevOpcode);
                }
                else
                {
                    if (field.Type.IsReferenceType)
                    {
                        if (prevOpcode == OpCodes.Ldnull)
                            modificationTypeDic[field] = FieldModificationType.NULL_SET;
                        else if (prevOpcode == OpCodes.Newarr || prevOpcode == OpCodes.Newobj)
                            modificationTypeDic[field] = FieldModificationType.NON_NULL_SET;
                        else
                            host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                                "Encountered unknown modification type for reference type " + prevOpcode);
                    }
                    else if (fieldTypeStr == "System.Boolean")
                    {
                        if (prevOpcode == OpCodes.Ldc_I4_0)
                            modificationTypeDic[field] = FieldModificationType.FALSE_SET;
                        else if (prevOpcode == OpCodes.Ldc_I4_1)
                            modificationTypeDic[field] = FieldModificationType.TRUE_SET;
                        else
                            host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                                "Encountered unknown modification type for boolean type " + prevOpcode);
                    }
                }

                //A heuristic based approach for aliasing analysis for checking whether the field is directly
                //assigned any parameters
                if (LdArgOpCodes.Contains(prevOpcode))
                    directSetFields.Add(field);
            }
            return fieldDeclaringType;
        }
        /// <summary>
        /// Compares current uncovered locations with the previous uncovered locations
        /// </summary>
        internal void AnalyzePreviousAndCurrentUncoveredLoc(string currPUTSignature,
            out HashSet<string> allGivenUpLocations, out HashSet<string> allCoveredLocations,
            out HashSet<string> newUncoveredLocations, out bool hasSomeCoveredLocation,
            out bool bAllAreNewLocations, out bool bNoneAreNewLocations)
        {
            hasSomeCoveredLocation = false;
            bAllAreNewLocations = true;
            bNoneAreNewLocations = true;

            var resolvedPrevLocations = new SafeSet<string>();
            var bestFitnessValues = new SafeDictionary<string, int>();

            //This dictionary is constructed since the FactorySuggestionStore is based
            //on declarting type not on the explorable type, which can be different
            allGivenUpLocations = new HashSet<string>();
            allCoveredLocations = new HashSet<string>();
            tempAllLocationStore = new SafeDictionary<string, PersistentUncoveredLocationStore>();

            //All final suggested sequences of the current PUT
            var putspecificsequences = new List<MethodSignatureSequence>();

            foreach (var fss in this.FactorySuggestionsDictionary.Values)
            {
                foreach (var codelockey in fss.locationStoreSpecificSequences.Keys)
                {
                    var pucls = fss.locationStoreSpecificSequences[codelockey];
                    if (!pucls.IsDormat())  //Donot touch dormant persistent stores
                        tempAllLocationStore[codelockey] = pucls;
                }

                foreach (var givenUpLocation in fss.PermanentFailedUncoveredLocations)
                    allGivenUpLocations.Add(givenUpLocation);

                foreach (var coveredLocation in fss.SuccessfulCoveredLocations)
                    allCoveredLocations.Add(coveredLocation);

                //MethodSignatureSequenceList mssl;
                //if (fss.FinalPUTSequences.TryGetValue(currPUTSignature, out mssl))
                //{
                //    foreach (var seq in mssl.SequenceList)
                //    {
                //        if (!putspecificsequences.Contains(seq))
                //            putspecificsequences.Add(seq);
                //    }
                //}
            }

            var failedLocations = new SafeSet<PersistentUncoveredLocationStore>();
            //Traverse all uncovered locations
            foreach (var ucovLocList in this.UncoveredLocationDictionary.Values)
            {
                var locationStr = ucovLocList.Location.ToString();
                var key = UncoveredCodeLocationStore.GetKey(ucovLocList.Location.ToString(),
                    ucovLocList.ExplorableType.ToString(), ucovLocList.TermIndex);

                //Check whether there are any defect detecting sequences. If yes promote them
                //in the associated factory store
                foreach (var ucls in ucovLocList.StoreList)
                {
                    if (ucls.IsADefectDetectingSequence)
                    {
                        var fss = this.FactorySuggestionsDictionary[ucls.ExplorableType.ToString()];
                        SafeDebug.AssumeNotNull(fss, "fss cannot be null");
                        fss.AddToDefectDetectingSequences(ucls.MethodCallSequence);
                    }
                }

                if (allGivenUpLocations.Contains(key))
                {
                    //This location has been earlier given up. No need to deal with this
                    resolvedPrevLocations.Add(key);
                    this.Log.LogMessage(WikiTopics.MissingWikiTopic, "Location " + locationStr + " is ignored since it was already given up earlier!!!");
                    continue;
                }

                if (allCoveredLocations.Contains(key))
                {
                    //This location has been covered earlier. Ideally this case should not happen
                    //resolvedPrevLocations.Add(key);
                    this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                        "Location " + locationStr + " is previously covered, but can be reported since the caller could be different.");
                    bAllAreNewLocations = false;
                    //continue;
                }

                //Get the associated factory suggestion store
                if (tempAllLocationStore.ContainsKey(key))
                {
                    bAllAreNewLocations = false;
                    var pucls = tempAllLocationStore[key];
                    resolvedPrevLocations.Add(key);

                    //For some formats such as TRUE_SET, we do not need the fitness measure
                    //If they are not covered in one attempt, they won't be covered any time
                    if (ucovLocList.StoreList.Count > 0)
                    {
                        var fmt = ucovLocList.StoreList[0].DesiredFieldModificationType;
                        if (!this.IsFitnessRequired(fmt))
                        {
                            pucls.NumberOfUnsuccessfulAttempts = PexMeConstants.MAX_UNSUCCESSFUL_ATTEMPTS + 1;
                        }
                    }

                    //Reached the threshold of number of attempts. So deleting this uncovered location forever
                    if (pucls.NumberOfUnsuccessfulAttempts + 1 <= PexMeConstants.MAX_UNSUCCESSFUL_ATTEMPTS)
                    {
                        //Handle according to fitness value and drop the other methods that
                        //acutally did not help increase the fitness value
                        this.RemoveSuggestionsWithLowFitness(ucovLocList, tempAllLocationStore[key], putspecificsequences);
                        this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                        "Location " + locationStr + " is resolved and is still uncovered in the new run " +
                        "(fitness: " + pucls.Fitnessvalue + "), (Attempt: " + pucls.NumberOfUnsuccessfulAttempts + ")");
                    }
                    else
                    {
                        this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                        "Location " + locationStr + " is resolved and but not making any process!!! Will be deleted forever");
                        //This pucls data will be deleted forever since it reached its max attempts without any progress
                        failedLocations.Add(pucls);
                    }
                }
            }

            //New locations that added to the factory suggestion store
            newUncoveredLocations = new HashSet<string>();
            foreach (var ucovLocList in this.UncoveredLocationDictionary.Values)
            {
                var key = UncoveredCodeLocationStore.GetKey(ucovLocList.Location.ToString(),
                        ucovLocList.ExplorableType.ToString(), ucovLocList.TermIndex);
                if (!resolvedPrevLocations.Contains(key))
                {
                    newUncoveredLocations.Add(key);
                    this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                        "Location " + ucovLocList.Location.ToString() + " is newly added in the new run");
                    bNoneAreNewLocations = false;
                }
            }

            //Unresolved locations from the previous run. This means that these sequences
            //are either already covered or not covered due to some new exception...
            var unresolvedPrevLocations = new SafeSet<PersistentUncoveredLocationStore>();
            var alreadyCoveredLocations = new SafeSet<PersistentUncoveredLocationStore>();
            foreach (var fss in this.FactorySuggestionsDictionary.Values)
            {
                var allRemovedPUCLS = new List<PersistentUncoveredLocationStore>();

                //Delete all failed locations if the suggested methods for this
                //failed location are all actually already explored. If not, place
                //them in pending status. Usually this case happens, if covering
                //the same location within the method is required by another location
                foreach (var pucls in failedLocations)
                {
                    var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation.ToString(),
                        pucls.ExplorableType.ToString(), pucls.TermIndex);

                    fss.RemoveUncoveredLocationStore(pucls, false, this);
                    allRemovedPUCLS.Add(pucls);
                }

                foreach (var codelockey in fss.locationStoreSpecificSequences.Keys)
                {
                    var tpucls = fss.locationStoreSpecificSequences[codelockey];
                    if (tpucls.IsDormat())
                        continue;

                    if (allGivenUpLocations.Contains(codelockey))
                    {
                        bAllAreNewLocations = false;
                        unresolvedPrevLocations.Add(tpucls);
                        this.Log.LogWarning(WikiTopics.MissingWikiTopic, "UncoveredLocation",
                            "Location " + codelockey + " was already given up. Should not be reported again!!! Anyways, Deleting this location forever");
                        continue;
                    }

                    if (!resolvedPrevLocations.Contains(codelockey))
                    {
                        //Check whether this location is covered based on the coverage
                        if (tpucls.AlreadyCovered || this.IsPrevUncoveredLocationCovered(tpucls))
                        {
                            alreadyCoveredLocations.Add(tpucls);
                            this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                                "Location " + codelockey + " is successfully covered in the new run");
                            hasSomeCoveredLocation = true;
                        }
                        else
                        {
                            bAllAreNewLocations = false;
                            unresolvedPrevLocations.Add(tpucls);
                            this.Log.LogWarning(WikiTopics.MissingWikiTopic, "UncoveredLocation",
                                "Location " + codelockey + " from the previous run is not found in the new run!!! Deleting this location forever");
                        }
                    }
                }

                //Delete all unresolved locations as they won't be required anymore!!!
                foreach (var pucls in unresolvedPrevLocations)
                {
                    fss.RemoveUncoveredLocationStore(pucls, false, this);
                    allRemovedPUCLS.Add(pucls);
                }

                //Handle all removed PUCLS
                foreach (var pucls in allRemovedPUCLS)
                {
                    var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation, pucls.ExplorableType, pucls.TermIndex);
                    fss.PermanentFailedUncoveredLocations.Add(key);
                    if (!fss.TemporaryFailedUncoveredLocations.ContainsKey(key))
                    {
                        //Are there any active uncovered locations
                        if (this.AnyActiveUncoveredLocations())
                            fss.TemporaryFailedUncoveredLocations[key] = 1;
                        else
                            fss.TemporaryFailedUncoveredLocations[key] = PexMeConstants.MAX_UNCOVEREDLOC_ATTEMPTS;
                    }
                }

                //Delete all the information regarding covered locations and upgrade their specific factory methods
                foreach (var pucls in alreadyCoveredLocations)
                {
                    fss.RemoveUncoveredLocationStore(pucls, true, this);
                }

                alreadyCoveredLocations.Clear();
            }
        }
        /// <summary>
        /// Gets calling methods of a given called method on the given field in a given target type
        /// </summary>
        /// <returns></returns>
        public bool TryGetCallingMethodsInType(Method calledMethod, Field field, TypeEx targetType, out SafeSet<Method> callingMethods)
        {
            SafeDebug.AssumeNotNull(calledMethod, "method");
            SafeDebug.AssumeNotNull(targetType, "type");

            //Get the associated property of the field
            Property property;
            if (!MethodOrFieldAnalyzer.TryGetPropertyReadingField(this, targetType, field, out property))
            {
                //TODO: error;
            }

            MethodStore mstore = null;
            if (this.MethodDictionary.TryGetValue(calledMethod, out mstore))
            {
                if (mstore.CallingMethods.TryGetValue(targetType, out callingMethods))
                    return true;
            }

            //No method store found. create a fresh one
            if (mstore == null)
            {
                mstore = new MethodStore();
                mstore.methodName = calledMethod;
                this.MethodDictionary[calledMethod] = mstore;
            }

            callingMethods = new SafeSet<Method>();
            mstore.CallingMethods[targetType] = callingMethods;
            TypeEx calledMethodType;
            if (!calledMethod.TryGetDeclaringType(out calledMethodType))
            {
                this.Log.LogError(WikiTopics.MissingWikiTopic, "callingmethods",
                    "Failed to get the declaring type for the method " + calledMethod.FullName);
                return false;
            }

            //Needs to addess the array type issue over here.
            var targetdef = targetType.Definition;
            if (targetdef == null)
            {
                if (targetType.TypeKind != TypeKind.SzArrayElements)
                {
                    this.Log.LogError(WikiTopics.MissingWikiTopic, "callingmethods",
                        "The definition for the type " + targetType.FullName + " is null");
                    return false;
                }
                else
                {
                    targetdef = targetType.ElementType.Definition;
                }
            }

            //Analyze each method in the given type to identify the calling methods
            //of the given method
            foreach (var typeMethod in targetdef.DeclaredInstanceMethods)
            {
                Method minstance = typeMethod.Instantiate(targetType.GenericTypeArguments, MethodOrFieldAnalyzer.GetGenericMethodParameters(this, typeMethod));

                MethodEffects meffects;
                if (!MethodOrFieldAnalyzer.TryComputeMethodEffects(this, targetType, minstance, null, out meffects))
                    continue;

                //Check for a direct comparison
                if (meffects.DirectCalledMethods.Contains(calledMethod))
                    callingMethods.Add(minstance);
                else
                {
                    //Use vtable lookup for addressing the abstract issues
                    foreach (var dcallMethod in meffects.DirectCalledMethods)
                    {
                        if (dcallMethod.IsConstructor)
                            continue;

                        TypeEx dcallMethodType;
                        if (dcallMethod.TryGetDeclaringType(out dcallMethodType))
                        {
                            if (dcallMethodType == calledMethodType || !dcallMethodType.IsAbstract || !dcallMethodType.IsInterface)
                                continue;

                            if (!dcallMethodType.IsAssignableTo(calledMethodType) && !calledMethodType.IsAssignableTo(dcallMethodType))
                                continue;
                        }

                        try
                        {
                            var lookupMethod = calledMethodType.VTableLookup(dcallMethod);
                            if (lookupMethod != null && calledMethod == lookupMethod)
                            {
                                callingMethods.Add(minstance);
                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            this.Log.LogWarningFromException(ex, WikiTopics.MissingWikiTopic,
                                "vtablelookup", "Failed to perform vtablelookup for " + dcallMethod.FullName + " in type " + calledMethodType.FullName);
                        }
                    }
                }
            }

            //Check whether there are any private methods in calling methods.
            //If yes, replace them with their callers.
            if (!PexMeConstants.DISABLE_CALLING_METHODS_WITHIN_CLASS)
            {
                var newCallingMethods = new SafeSet<Method>();
                foreach (var callingM in callingMethods)
                {
                    if (callingM.Definition.DeclaredVisibility != Visibility.Private || callingM.IsConstructor)
                    {
                        newCallingMethods.Add(callingM);
                        continue;
                    }

                    //Get other calling methods within this type
                    SafeSet<Method> localCM;
                    if (this.TryGetCallingMethodsInType(callingM, field, targetType, out localCM))
                    {
                        newCallingMethods.AddRange(localCM);
                    }
                }

                callingMethods.Clear();
                callingMethods.AddRange(newCallingMethods);
            }

            //Needs to further analyze parent types
            TypeEx baseType = targetType.BaseType;
            if (baseType != null && baseType.FullName != "System.Object")   //TODO: Avoid string comparisons. needs to figure out how to do that
            {
                SafeSet<Method> baseCallingMethods;
                TryGetCallingMethodsInType(calledMethod, field, baseType, out baseCallingMethods);
                callingMethods.AddRange(baseCallingMethods);
            }

            return true;
        }
 /// <summary>
 /// Generates nested command files. Ignores if there are any PUTs in 
 /// pmd.PendingExplorationMethods since those methods can cause cycles.
 /// </summary>
 /// <param name="allSuggestedNewPUTs"></param>
 /// <param name="cmdfile"></param>
 private void GenerateNestedCommandFile(SafeSet<Method> allSuggestedNewPUTs, string cmdfile)
 {
     using (StreamWriter sw = new StreamWriter(cmdfile))
     {
         foreach (var newput in allSuggestedNewPUTs)
         {
             var newputsig = MethodOrFieldAnalyzer.GetMethodSignature(newput);
             sw.WriteLine(PUTGenerator.PUTGenerator.GeneratePUTCommand(newput));
         }
     }
 }
        /// <summary>
        /// Computes method effects statically. All written fields of a method.
        /// Can be imprecise and conservative
        /// </summary>
        /// <param name="declaringType"></param>
        /// <param name="method"></param>
        /// <param name="effects"></param>
        /// <returns></returns>
        public static bool TryComputeMethodEffects(IPexComponent host, TypeEx declaringType, Method method,
            SafeSet<Method> visitedMethods, out MethodEffects effects)
        {
            SafeDebug.AssumeNotNull(declaringType, "declaringType");
            SafeDebug.AssumeNotNull(method, "method");

            try
            {
                if (visitedMethods == null)
                    visitedMethods = new SafeSet<Method>();

                if (visitedMethods.Contains(method))
                {
                    effects = null;
                    return false;
                }

                visitedMethods.Add(method);

                //Check whether this has been computed before
                var psd = host.GetService<IPexMeStaticDatabase>() as PexMeStaticDatabase;
                if (psd.MethodEffectsDic.TryGetValue(method.GlobalIndex, out effects))
                    return true;

                var res = new SafeSet<string>();
                var directSetFields = new SafeSet<string>();
                var directCalledMethods = new SafeSet<Method>();
                var returnFields = new SafeSet<Field>();
                var modificationTypeDic = new SafeDictionary<string, FieldModificationType>();
                var parameters = method.Parameters;

                MethodBodyEx body;
                if (!method.TryGetBody(out body) || !body.HasInstructions)
                {
                    effects = null;
                    return false;
                }

                int callDepth = 0;
                int offset = 0;
                Instruction instruction;
                OpCode prevOpcode = OpCodes.Nop;

                //Stack for load instructions
                Field lastAccessedArrayField = null;
                Field lastAccessedField = null;

                while (body.TryGetInstruction(offset, out instruction))
                {
                    SafeDebug.AssumeNotNull(instruction, "instruction");
                    OpCode opCode = instruction.OpCode;
                    if (LdcOpCodes.Contains(opCode))
                    {
                        //topIsConstant = true;
                    }
                    else if (ConvOpCodes.Contains(opCode))
                    {
                        // do not change topIsConstant
                    }
                    else
                    {
                        if (opCode == OpCodes.Stfld)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                            Field field = instruction.Field;
                            AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, field, field.Type);
                        }
                        else if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldflda)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                            Field accessedField = instruction.Field;

                            if (accessedField.Type.Spec == TypeSpec.SzArray)
                            {
                                lastAccessedArrayField = accessedField;
                            }
                            else
                                lastAccessedField = accessedField;
                        }
                        else if (StElemOpCodes.Contains(opCode))
                        {
                            if (lastAccessedArrayField != null)
                            {
                                //Indicates that there is n array type modified
                                AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, lastAccessedArrayField, lastAccessedArrayField.Type);
                                lastAccessedArrayField = null;
                            }
                        }
                        else if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod, "opCode.OperandType == OperandType.InlineMethod");
                            Method methodinner = instruction.Method;
                            SafeDebug.AssumeNotNull(method, "method");

                            directCalledMethods.Add(methodinner);
                            TypeEx methodDeclaringType;

                            //are these function calls are within the parent types
                            if (methodinner.TryGetDeclaringType(out methodDeclaringType) &&
                                declaringType.IsAssignableTo(methodDeclaringType))
                            {
                                MethodEffects methodEffects;
                                if (TryComputeMethodEffects(host, methodDeclaringType, methodinner, visitedMethods, out methodEffects))
                                {
                                    res.AddRange(methodEffects.WrittenInstanceFields);
                                    foreach (var key in methodEffects.ModificationTypeDictionary.Keys)
                                        modificationTypeDic[key] = methodEffects.ModificationTypeDictionary[key];
                                    directSetFields.AddRange(methodEffects.DirectSetterFields);
                                    if (methodEffects.CallDepth > callDepth)
                                        callDepth = methodEffects.CallDepth;
                                }
                            }
                            else
                            {
                                //introducing heuristics for inter-procedural static analysis
                                if (lastAccessedField != null && lastAccessedField.Type.IsReferenceType &&
                                    !(methodinner.ShortName.StartsWith("Get") || methodinner.ShortName.StartsWith("get")
                                    || methodinner.ShortName.StartsWith("Set") || methodinner.ShortName.StartsWith("set")))
                                {
                                    AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic,
                                        prevOpcode, lastAccessedField, lastAccessedField.Type);
                                }
                            }
                        }
                        else if (opCode == OpCodes.Ret)
                        {
                            if (instruction.Field != null)
                                returnFields.Add(instruction.Field);
                        }
                        //topIsConstant = false;
                    }

                    prevOpcode = opCode;
                    offset = instruction.NextOffset;
                }

                effects = new MethodEffects((IFiniteSet<string>)res, directSetFields, directCalledMethods, returnFields, modificationTypeDic, callDepth + 1);
                psd.MethodEffectsDic[method.GlobalIndex] = effects;
                return true;
            }
            catch (Exception ex)
            {
                host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "methodeffects",
                    "Failed to compute method effects for method " + method.FullName + "," + ex.Message);
                effects = null;
                return false;
            }
        }
Beispiel #41
0
        /// <summary>
        /// If type is an interface, returns all concrete implementing classes
        /// else if type is an abstract class, returns all concrete extending classes
        /// </summary>
        /// <param name="psd"></param>
        /// <param name="type"></param>
        /// <param name="extendingClasses"></param>
        /// <returns></returns>
        public static bool TryGetExtendingClasses(PexMeStaticDatabase psd, TypeEx type, out IIndexable<TypeDefinition> extendingClasses)
        {
            //load inheritance hierarchies if not already done
            psd.LoadInheritanceHierarchies();
            extendingClasses = null;

            TypeStore ts;
            if (!psd.TypeDictionary.TryGetValue(type.Definition, out ts))
                return false;

            SafeSet<TypeDefinition> extendingClassesSet = new SafeSet<TypeDefinition>();
            CollectAllExtendingClasses(ts, extendingClassesSet);

            if (extendingClassesSet.Count == 0)
                return false;

            var extendingClassesList = new SafeList<TypeDefinition>();
            foreach (var tdef in extendingClassesSet)
            {
                extendingClassesList.Add(tdef);
            }

            extendingClasses = extendingClassesList;
            return true;
        }
        /// <summary>
        /// Filters out covered code locations
        /// </summary>
        public void FilterOutCoveredCodeLocations()
        {
            //Finding out covered locations
            //Also Finding out other locations in system libraries
            //that do not contribute to increase in the covered. Those
            //libraries should also be removed
            var coveredLocations = new SafeSet<UncoveredCodeLocationStoreList>();
            foreach (var uclStoreList in this.UncoveredLocationDictionary.Values)
            {
                var cl = uclStoreList.Location;
                if (this.IsBranchOffsetCoveredInMethod(cl.Method, cl.Offset))
                {
                    coveredLocations.Add(uclStoreList);
                }
                else
                {
                    //Check whether the uncoverd location is in system library
                    var currAssembly = this.Services.CurrentAssembly.Assembly.Assembly;
                    bool bDeleteUCList = true;

                    foreach (var ucstore in uclStoreList.StoreList)
                    {
                        //Check the CUTMethodCall sequence in the ucstore to decide
                        //whether to continue with this
                        foreach (var method in ucstore.CUTMethodCallSequence)
                        {
                            var methoddef = method.Definition;
                            if (methoddef.Module.Assembly == currAssembly && !this.AreAllOffsetsCoveredInMethod(method))
                            {
                                bDeleteUCList = false;
                                break;
                            }
                        }

                        if (!bDeleteUCList)
                            break;
                    }

                    if (bDeleteUCList)
                        coveredLocations.Add(uclStoreList);
                }
            }

            foreach (var covered in coveredLocations)
            {
                var key = UncoveredCodeLocationStore.GetKey(covered.Location.ToString(), covered.ExplorableType, covered.TermIndex);
                this.UncoveredLocationDictionary.Remove(key);
            }
        }
        /// <summary>
        /// Makes a mapping relationship between a calling method and a called method
        /// </summary>
        /// <param name="callingMethod"></param>
        /// <param name="calledMethod"></param>
        public void AddMethodMapping(Method callingMethod, Method calledMethod)
        {
            //Updating the method store for calling methods
            MethodStore callingMethodStore = null;
            if (!methodDic.TryGetValue(callingMethod, out callingMethodStore))
            {
                callingMethodStore = new MethodStore();
                callingMethodStore.methodName = calledMethod;
                methodDic[callingMethod] = callingMethodStore;
            }
            callingMethodStore.CalledMethods.Add(calledMethod);

            //Updating the method store for called methods
            MethodStore calledMethodStore = null;
            if(!methodDic.TryGetValue(calledMethod, out calledMethodStore))
            {
                calledMethodStore = new MethodStore();
                calledMethodStore.methodName = calledMethod;
                methodDic[calledMethod] = calledMethodStore;
            }

            TypeEx callingMethodType;
            if (!callingMethod.TryGetDeclaringType(out callingMethodType))
            {
                this.Log.LogError(WikiTopics.MissingWikiTopic, "methodmapping",
                    "Failed to get the declared type for method " + calledMethod);
                return;
            }

            SafeSet<Method> localCallingMethods;
            if (!calledMethodStore.CallingMethods.TryGetValue(callingMethodType, out localCallingMethods))
            {
                localCallingMethods = new SafeSet<Method>();
                calledMethodStore.CallingMethods[callingMethodType] = localCallingMethods;
            }
            localCallingMethods.Add(callingMethod);
        }
        /// <summary>
        /// Gets the target method that need to be invoked for setting a field.
        /// Based on static analysis and later uses dynamic analysis for giving
        /// more priority to those methods that are identified through dynamic analysis also.
        /// </summary>
        /// <param name="ucls"></param>
        /// <param name="targetField"></param>
        /// <param name="declaringType"></param>
        /// <param name="targetMethods"></param>
        /// <returns></returns>
        private bool GetTargetMethod(UncoveredCodeLocationStore ucls, Field targetField,
                                     out SafeSet <Method> targetMethods)
        {
            targetMethods = new SafeSet <Method>();

            int numfields = ucls.AllFields.Count;

            for (int count = 0; count < numfields; count++)
            {
                var field = ucls.AllFields[count];

                //Get all write methods for this field
                SafeSet <Method> writeMethods = null;

                //Get the declaring type of the field. There are two possibilities of choosing
                //a declaring type: from the next field or the enclosing type
                TypeEx declaringType1 = null, declaringType2 = null;

                //If there is a parent field, the declaring type should
                //be upgraded to the type of the next field in the list, which could be
                //a sub-class of the actual declaring type
                if (count < numfields - 1)
                {
                    var nextField = ucls.AllFields[count + 1];
                    declaringType1 = nextField.Type;
                }

                if (!MethodOrFieldAnalyzer.TryGetDeclaringTypeEx(this.host, field, out declaringType2))
                {
                    SafeDebug.AssumeNotNull(declaringType2, "declaringType");
                }

                var declaringType = declaringType2;
                if (declaringType1 != null && declaringType1 != declaringType2)
                {
                    declaringType = this.ChooseADeclaringType(declaringType1, declaringType2);
                }

                //Chosen declaringType should be a part of all field types stored
                //in UCLS. If not, there can be inheritance issues
                if (!ucls.AllFieldTypes.Contains(declaringType))
                {
                    //Find out the type to which declaringType is assignable and update it
                    foreach (var tex in ucls.AllFieldTypes)
                    {
                        if (tex.IsAssignableTo(declaringType))
                        {
                            declaringType = tex;
                            break;
                        }
                    }
                }

                //For the first field, get all the methods that modify the field
                //using static analysis
                if (targetMethods.Count == 0)
                {
                    //Try from static analysis store
                    if (!this.psd.TryGetFilteredWriteMethods(field, declaringType, ucls.DesiredFieldModificationType, out writeMethods))
                    {
                        this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                 "Failed to get write methods for the field " + field.FullName);
                        return(false);
                    }

                    //Try from dynamic analysis
                    //if (!this.pmd.FieldDictionary.TryGetValue(field.GlobalIndex, out fs))
                    targetMethods.AddRange(writeMethods);
                }
                else
                {
                    //Get the callers of all methods in targetmethods
                    SafeSet <Method> callerMethods = new SafeSet <Method>();
                    foreach (var tmw in targetMethods)
                    {
                        SafeSet <Method> callingMethods;

                        //TODO: Performance improvements can be done here as we repeat the loops inside
                        //the method for each method in targetMethods
                        if (!this.psd.TryGetCallingMethodsInType(tmw, field, declaringType, out callingMethods))
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                     SafeString.Format("Failed to get calling methods of {0} through static and dynamic analysis", tmw));
                            continue;
                        }

                        //Filter the called methods based on field to avoid
                        //unnecessary additional methods
                        SafeSet <Method> subcallingMethods = this.psd.FilterCallingMethodsBasedOnField(tmw, field, callingMethods);
                        if (callingMethods.Count > 0 && subcallingMethods.Count == 0)
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "callingmethods",
                                                     "Failed to filter calling methods based on field, adding all methods");
                            subcallingMethods.AddRange(callingMethods);
                        }

                        //Check in dynamic analysis portion
                        //if (!this.pmd.MethodDictionary.TryGetValue(tmw.GlobalIndex, out mstore))
                        //{
                        //}
                        //else
                        //    callingMethods = mstore.CallingMethods[declaringType];

                        callerMethods.AddRange(subcallingMethods);
                    }

                    //All caller methods in the parent type
                    targetMethods = callerMethods;
                }

                //Our objective is to search for the methods that belong to our target field.
                //Stop traversal once the desired method is found
                if (field == targetField)
                {
                    break;
                }
            }

            return(true);
        }
        /// <summary>
        /// Includes filtering of the methods based on desired format
        /// </summary>
        /// <returns></returns>
        public bool TryGetFilteredWriteMethods(Field field, TypeEx declaringType, FieldModificationType desiredfmt, out SafeSet<Method> writeMethods)
        {
            //Check in the predefined store before proceeding
            if (PreDefinedMethodEffects.TryGetWriteMethods(this, field, desiredfmt, out writeMethods))
            {
                SafeSet<Method> newWriteMethods = new SafeSet<Method>();
                GetCallingMethods(field, declaringType, writeMethods, newWriteMethods);

                //Filter those methods whose actual types are abstract
                SafeSet<Method> returnMethods = new SafeSet<Method>();
                foreach (Method m in writeMethods)
                {
                    TypeEx declType;
                    if (m.TryGetDeclaringType(out declType) && !declType.IsAbstract && !declType.IsInterface)
                    {
                        returnMethods.Add(m);
                    }
                }

                foreach (Method m in newWriteMethods)
                {
                    TypeEx declType;
                    if (m.TryGetDeclaringType(out declType) && !declType.IsAbstract && !declType.IsInterface)
                    {
                        returnMethods.Add(m);
                    }
                }

                writeMethods.Clear();
                writeMethods.AddRange(returnMethods);
                return true;
            }

            //Identify those method that directly modify this field
            if (!TryGetWriteMethods(field, declaringType, out writeMethods))
                return false;

            //C# supports properties. In that case, the property setter can also
            //be a viable method. add property setter and its callers also
            Property property;
            if (MethodOrFieldAnalyzer.TryGetPropertyModifyingField(this, declaringType, field, out property))
            {
                if (property.IsVisible(VisibilityContext.Exported))
                    writeMethods.Add(property.Setter);

                var newWriteMethods = new SafeSet<Method>();
                GetCallingMethods(field, declaringType, writeMethods, newWriteMethods);
                writeMethods.AddRange(newWriteMethods);
            }

            writeMethods = FilterWriteMethodsOfUpdateType(field, desiredfmt, writeMethods);
            return true;
        }
Beispiel #46
0
        /// <summary>
        /// Compares current uncovered locations with the previous uncovered locations
        /// </summary>
        internal void AnalyzePreviousAndCurrentUncoveredLoc(string currPUTSignature,
                                                            out HashSet <string> allGivenUpLocations, out HashSet <string> allCoveredLocations,
                                                            out HashSet <string> newUncoveredLocations, out bool hasSomeCoveredLocation,
                                                            out bool bAllAreNewLocations, out bool bNoneAreNewLocations)
        {
            hasSomeCoveredLocation = false;
            bAllAreNewLocations    = true;
            bNoneAreNewLocations   = true;

            var resolvedPrevLocations = new SafeSet <string>();
            var bestFitnessValues     = new SafeDictionary <string, int>();

            //This dictionary is constructed since the FactorySuggestionStore is based
            //on declarting type not on the explorable type, which can be different
            allGivenUpLocations  = new HashSet <string>();
            allCoveredLocations  = new HashSet <string>();
            tempAllLocationStore = new SafeDictionary <string, PersistentUncoveredLocationStore>();

            //All final suggested sequences of the current PUT
            var putspecificsequences = new List <MethodSignatureSequence>();

            foreach (var fss in this.FactorySuggestionsDictionary.Values)
            {
                foreach (var codelockey in fss.locationStoreSpecificSequences.Keys)
                {
                    var pucls = fss.locationStoreSpecificSequences[codelockey];
                    if (!pucls.IsDormat())  //Donot touch dormant persistent stores
                    {
                        tempAllLocationStore[codelockey] = pucls;
                    }
                }

                foreach (var givenUpLocation in fss.PermanentFailedUncoveredLocations)
                {
                    allGivenUpLocations.Add(givenUpLocation);
                }

                foreach (var coveredLocation in fss.SuccessfulCoveredLocations)
                {
                    allCoveredLocations.Add(coveredLocation);
                }

                //MethodSignatureSequenceList mssl;
                //if (fss.FinalPUTSequences.TryGetValue(currPUTSignature, out mssl))
                //{
                //    foreach (var seq in mssl.SequenceList)
                //    {
                //        if (!putspecificsequences.Contains(seq))
                //            putspecificsequences.Add(seq);
                //    }
                //}
            }

            var failedLocations = new SafeSet <PersistentUncoveredLocationStore>();

            //Traverse all uncovered locations
            foreach (var ucovLocList in this.UncoveredLocationDictionary.Values)
            {
                var locationStr = ucovLocList.Location.ToString();
                var key         = UncoveredCodeLocationStore.GetKey(ucovLocList.Location.ToString(),
                                                                    ucovLocList.ExplorableType.ToString(), ucovLocList.TermIndex);

                //Check whether there are any defect detecting sequences. If yes promote them
                //in the associated factory store
                foreach (var ucls in ucovLocList.StoreList)
                {
                    if (ucls.IsADefectDetectingSequence)
                    {
                        var fss = this.FactorySuggestionsDictionary[ucls.ExplorableType.ToString()];
                        SafeDebug.AssumeNotNull(fss, "fss cannot be null");
                        fss.AddToDefectDetectingSequences(ucls.MethodCallSequence);
                    }
                }

                if (allGivenUpLocations.Contains(key))
                {
                    //This location has been earlier given up. No need to deal with this
                    resolvedPrevLocations.Add(key);
                    this.Log.LogMessage(WikiTopics.MissingWikiTopic, "Location " + locationStr + " is ignored since it was already given up earlier!!!");
                    continue;
                }

                if (allCoveredLocations.Contains(key))
                {
                    //This location has been covered earlier. Ideally this case should not happen
                    //resolvedPrevLocations.Add(key);
                    this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                                        "Location " + locationStr + " is previously covered, but can be reported since the caller could be different.");
                    bAllAreNewLocations = false;
                    //continue;
                }

                //Get the associated factory suggestion store
                if (tempAllLocationStore.ContainsKey(key))
                {
                    bAllAreNewLocations = false;
                    var pucls = tempAllLocationStore[key];
                    resolvedPrevLocations.Add(key);

                    //For some formats such as TRUE_SET, we do not need the fitness measure
                    //If they are not covered in one attempt, they won't be covered any time
                    if (ucovLocList.StoreList.Count > 0)
                    {
                        var fmt = ucovLocList.StoreList[0].DesiredFieldModificationType;
                        if (!this.IsFitnessRequired(fmt))
                        {
                            pucls.NumberOfUnsuccessfulAttempts = PexMeConstants.MAX_UNSUCCESSFUL_ATTEMPTS + 1;
                        }
                    }

                    //Reached the threshold of number of attempts. So deleting this uncovered location forever
                    if (pucls.NumberOfUnsuccessfulAttempts + 1 <= PexMeConstants.MAX_UNSUCCESSFUL_ATTEMPTS)
                    {
                        //Handle according to fitness value and drop the other methods that
                        //acutally did not help increase the fitness value
                        this.RemoveSuggestionsWithLowFitness(ucovLocList, tempAllLocationStore[key], putspecificsequences);
                        this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                                            "Location " + locationStr + " is resolved and is still uncovered in the new run " +
                                            "(fitness: " + pucls.Fitnessvalue + "), (Attempt: " + pucls.NumberOfUnsuccessfulAttempts + ")");
                    }
                    else
                    {
                        this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                                            "Location " + locationStr + " is resolved and but not making any process!!! Will be deleted forever");
                        //This pucls data will be deleted forever since it reached its max attempts without any progress
                        failedLocations.Add(pucls);
                    }
                }
            }

            //New locations that added to the factory suggestion store
            newUncoveredLocations = new HashSet <string>();
            foreach (var ucovLocList in this.UncoveredLocationDictionary.Values)
            {
                var key = UncoveredCodeLocationStore.GetKey(ucovLocList.Location.ToString(),
                                                            ucovLocList.ExplorableType.ToString(), ucovLocList.TermIndex);
                if (!resolvedPrevLocations.Contains(key))
                {
                    newUncoveredLocations.Add(key);
                    this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                                        "Location " + ucovLocList.Location.ToString() + " is newly added in the new run");
                    bNoneAreNewLocations = false;
                }
            }

            //Unresolved locations from the previous run. This means that these sequences
            //are either already covered or not covered due to some new exception...
            var unresolvedPrevLocations = new SafeSet <PersistentUncoveredLocationStore>();
            var alreadyCoveredLocations = new SafeSet <PersistentUncoveredLocationStore>();

            foreach (var fss in this.FactorySuggestionsDictionary.Values)
            {
                var allRemovedPUCLS = new List <PersistentUncoveredLocationStore>();

                //Delete all failed locations if the suggested methods for this
                //failed location are all actually already explored. If not, place
                //them in pending status. Usually this case happens, if covering
                //the same location within the method is required by another location
                foreach (var pucls in failedLocations)
                {
                    var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation.ToString(),
                                                                pucls.ExplorableType.ToString(), pucls.TermIndex);

                    fss.RemoveUncoveredLocationStore(pucls, false, this);
                    allRemovedPUCLS.Add(pucls);
                }

                foreach (var codelockey in fss.locationStoreSpecificSequences.Keys)
                {
                    var tpucls = fss.locationStoreSpecificSequences[codelockey];
                    if (tpucls.IsDormat())
                    {
                        continue;
                    }

                    if (allGivenUpLocations.Contains(codelockey))
                    {
                        bAllAreNewLocations = false;
                        unresolvedPrevLocations.Add(tpucls);
                        this.Log.LogWarning(WikiTopics.MissingWikiTopic, "UncoveredLocation",
                                            "Location " + codelockey + " was already given up. Should not be reported again!!! Anyways, Deleting this location forever");
                        continue;
                    }

                    if (!resolvedPrevLocations.Contains(codelockey))
                    {
                        //Check whether this location is covered based on the coverage
                        if (tpucls.AlreadyCovered || this.IsPrevUncoveredLocationCovered(tpucls))
                        {
                            alreadyCoveredLocations.Add(tpucls);
                            this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                                                "Location " + codelockey + " is successfully covered in the new run");
                            hasSomeCoveredLocation = true;
                        }
                        else
                        {
                            bAllAreNewLocations = false;
                            unresolvedPrevLocations.Add(tpucls);
                            this.Log.LogWarning(WikiTopics.MissingWikiTopic, "UncoveredLocation",
                                                "Location " + codelockey + " from the previous run is not found in the new run!!! Deleting this location forever");
                        }
                    }
                }

                //Delete all unresolved locations as they won't be required anymore!!!
                foreach (var pucls in unresolvedPrevLocations)
                {
                    fss.RemoveUncoveredLocationStore(pucls, false, this);
                    allRemovedPUCLS.Add(pucls);
                }

                //Handle all removed PUCLS
                foreach (var pucls in allRemovedPUCLS)
                {
                    var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation, pucls.ExplorableType, pucls.TermIndex);
                    fss.PermanentFailedUncoveredLocations.Add(key);
                    if (!fss.TemporaryFailedUncoveredLocations.ContainsKey(key))
                    {
                        //Are there any active uncovered locations
                        if (this.AnyActiveUncoveredLocations())
                        {
                            fss.TemporaryFailedUncoveredLocations[key] = 1;
                        }
                        else
                        {
                            fss.TemporaryFailedUncoveredLocations[key] = PexMeConstants.MAX_UNCOVEREDLOC_ATTEMPTS;
                        }
                    }
                }

                //Delete all the information regarding covered locations and upgrade their specific factory methods
                foreach (var pucls in alreadyCoveredLocations)
                {
                    fss.RemoveUncoveredLocationStore(pucls, true, this);
                }

                alreadyCoveredLocations.Clear();
            }
        }
        /// <summary>
        /// Gets the set of write methods associated with a field in the given type
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public bool TryGetWriteMethods(Field field, TypeEx declaringType, out SafeSet<Method> writeMethods)
        {
            SafeDebug.AssumeNotNull(field, "field");
            SafeDebug.AssumeNotNull(declaringType, "declaringType");

            //Declaring type should include defintinion
            if (declaringType == null || declaringType.Definition == null)
            {
                this.Log.LogWarning(WikiTopics.MissingWikiTopic, "WriteMethods",
                    "Missing definition for the declaring type " + declaringType.FullName);
                writeMethods = null;
                return false;
            }

            FieldStore fs;
            if (this.FieldDictionary.TryGetValue(field, out fs))
            {
                if (fs.WriteMethods.TryGetValue(declaringType, out writeMethods))
                    return true;
                else
                {
                    writeMethods = new SafeSet<Method>();
                    fs.WriteMethods[declaringType] = writeMethods;
                }
            }
            else
            {
                fs = new FieldStore();
                fs.FieldName = field;
                writeMethods = new SafeSet<Method>();
                fs.WriteMethods[declaringType] = writeMethods;
                this.FieldDictionary[field] = fs;
            }

            foreach (MethodDefinition instanceMethod in declaringType.Definition.DeclaredInstanceMethods)
            {
                //Ignore abstract methods
                if (instanceMethod.IsAbstract)
                    continue;

                //If the DISABLE_CALLING_METHODS_WITHIN_CLASS is set to true, then private methods need not be considered
                //since they will be filtered out.
                if (PexMeConstants.DISABLE_CALLING_METHODS_WITHIN_CLASS && instanceMethod.DeclaredVisibility == Visibility.Private)
                    continue;

                Method method = instanceMethod.Instantiate(declaringType.GenericTypeArguments, MethodOrFieldAnalyzer.GetGenericMethodParameters(this, instanceMethod));
                MethodEffects me;

                if (!MethodOrFieldAnalyzer.TryComputeMethodEffects(this, declaringType, method, null, out me))
                {
                    this.Log.LogWarning(WikiTopics.MissingWikiTopic, "methodeffects",
                        "Failed to get the method effects for method " + method);
                    continue;
                }

                if (me.WrittenInstanceFields.Contains(field.ShortName))
                {
                    writeMethods.Add(method);
                }

                FieldModificationType fmt;
                if (me.ModificationTypeDictionary.TryGetValue(field.ShortName, out fmt))
                {
                    fs.ModificationTypeDictionary[method] = fmt;
                }
            }

            //Check whether there are any private methods in calling methods.
            //If yes, replace them with their callers.
            if (!PexMeConstants.DISABLE_CALLING_METHODS_WITHIN_CLASS)
            {
                var newWriteMethods = new SafeSet<Method>();
                GetCallingMethods(field, declaringType, writeMethods, newWriteMethods);

                writeMethods.Clear();
                writeMethods.AddRange(newWriteMethods);
            }

            TypeEx baseType = declaringType.BaseType;
            if (baseType != null && baseType.FullName != "System.Object")
            {
                SafeSet<Method> innerWriteMethods;
                this.TryGetWriteMethods(field, baseType, out innerWriteMethods);
                if (innerWriteMethods != null)
                    writeMethods.AddRange(innerWriteMethods);
            }

            return true;
        }
Beispiel #48
0
 public Fact()
 {
     _tupleComparer = TupleEqualityComparer <T> .Default;
     _data          = new SafeSet <Tuple <T> >(_tupleComparer);
 }
        internal SafeSet<Method> FilterCallingMethodsBasedOnField(Method tmw, Field field, 
            SafeSet<Method> callingMethods)
        {
            SafeSet<Method> filteredMethods = new SafeSet<Method>();

            foreach (var callingm in callingMethods)
            {
                //Filter the calling method based on the field
                MethodBodyEx body;
                if (!callingm.TryGetBody(out body) || !body.HasInstructions)
                {
                    continue;
                }

                int offset = 0;
                Instruction instruction;
                bool bContinueWithNextMethod = false;
                Field lastAccessedField = null;
                while (body.TryGetInstruction(offset, out instruction) && !bContinueWithNextMethod)
                {
                    SafeDebug.AssumeNotNull(instruction, "instruction");
                    OpCode opCode = instruction.OpCode;
                    if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldflda)
                    {
                        SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                        lastAccessedField = instruction.Field;
                    } else if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt)
                    {
                        SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod, "opCode.OperandType == OperandType.InlineMethod");
                        Method methodinner = instruction.Method;

                        if (methodinner == tmw && field == lastAccessedField)
                        {
                            filteredMethods.Add(callingm);
                            bContinueWithNextMethod = true;
                        }
                        lastAccessedField = null;
                    }
                    offset = instruction.NextOffset;
                }
            }
            return filteredMethods;
        }
        /// <summary>
        /// Helps guess factory methods for each uncovered condition
        /// </summary>
        private void GuessFactorymethods(out SafeSet<Method> allNewSuggestedPUTs, string currPUTSignature, out bool bHasSomeCoveredLocation,
            out bool bAllAreNewLocations, out bool bNoneAreNewLocations)
        {
            PexMeFactoryGuesser pfg = new PexMeFactoryGuesser(this.host);

            HashSet<string> allGivenUpLocations, allCoveredLocations, newUnCoveredLocations;
            //Analyze the current uncovered and previously uncovered locations
            this.pmd.AnalyzePreviousAndCurrentUncoveredLoc(currPUTSignature, out allGivenUpLocations,
                out allCoveredLocations, out newUnCoveredLocations, out bHasSomeCoveredLocation, out bAllAreNewLocations, out bNoneAreNewLocations);

            allNewSuggestedPUTs = new SafeSet<Method>();
            //Iterate through each uncovered location
            foreach (var ucovLocList in pmd.UncoveredLocationDictionary.Values)
            {
                //TODO: Classify the uncovered locations into different groups
                //Because, it can happen that a single code location can have multiple terms which
                //cannot be merged together.
                if (ucovLocList.StoreList.Count == 0)
                    continue;

                //Check whether this location is earlier attempted and is failed. no
                //need to try this location again
                FactorySuggestionStore fss = null;
                string key = null;
                if (this.pmd.FactorySuggestionsDictionary.TryGetValue(ucovLocList.ExplorableType, out fss))
                {
                    key = UncoveredCodeLocationStore.GetKey(ucovLocList.Location.ToString(),
                        ucovLocList.ExplorableType, ucovLocList.TermIndex);

                    //A fix to keep track of uncovered locations in system libraries
                    if (TargetBranchAnalyzer.IsUncoveredLocationInSystemLib(ucovLocList.Location))
                    {
                        fss.UncoveredSystemLibLocations.Add(key);
                    }

                    if (allGivenUpLocations.Contains(key))
                        continue;
                    //Already covered locations can be reported again due to different PUTs or different call sites
                    //if (allCoveredLocations.Contains(key))
                    //    continue;
                    if (fss.PermanentFailedUncoveredLocations.Contains(key))
                        continue;
                    //if (fss.SuccessfulCoveredLocations.Contains(key))
                    //    continue;
                }

                //A single element of ucovLoc is sufficient here
                var ucovLoc = ucovLocList.StoreList[0];
                if (!pfg.TryInferFactoryMethod(ucovLoc, out ucovLoc.SuggestedMethodSetforFactory))
                {
                    this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "postprocessor",
                        "Failed to suggest factory methods for uncovered location " + ucovLoc.ToString() + " -> Adding to permanent failed locations");

                    if (fss != null && key != null)
                        fss.PermanentFailedUncoveredLocations.Add(key);

                    continue;
                }

                //If a suggested method is not yet explored, add it to all new suggested method
                if (ucovLoc.SuggestedMethodSetforFactory != null)
                {
                    foreach (var suggestedm in ucovLoc.SuggestedMethodSetforFactory)
                    {
                        if (suggestedm.IsConstructor)
                            continue;

                        //Check if this is ever explored by this process by getting associated PUT
                        Method pexmethod;
                        bool bretval = PUTGenerator.PUTGenerator.TryRetrievePUT(this.pmd, this.currAssembly, suggestedm, out pexmethod);
                        if (!bretval)
                        {
                            //The suggested method is out of scope of current library and
                            //no need to explore it explicitly
                            continue;
                        }

                        //Ignore self suggestions
                        if (pexmethod == this.pmd.CurrentPUTMethod)
                            continue;
                        var signature = MethodOrFieldAnalyzer.GetMethodSignature(pexmethod);
                        if (this.pmd.AllExploredMethods.Contains(signature))
                            continue;

                        if (this.pmd.PendingExplorationMethods.Contains(signature))
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic,
                                "Nested PUTs", "Ignoring the nested PUT due to cycle detection " + signature);
                            continue;
                        }

                        allNewSuggestedPUTs.Add(pexmethod);
                    }
                }
            }
        }
        /// <summary>
        /// Adds a monitored field to the database. Updates two kinds of hashmaps
        /// a. Field to Method mapper, which gives what the methods modifying a given field
        /// b. Method to Field mapper, which gives what fields are modified by each method (later used to identify a minimized set of methods)
        /// </summary>
        /// <param name="tm"></param>
        /// <param name="method"></param>
        /// <param name="f"></param>
        /// <param name="indices"></param>
        /// <param name="fieldValue"></param>
        public void AddMonitoredField(TermManager tm, Method method, Field f, Term[] indices, Term fieldValue, Term initialValue)
        {
            string arrayIndex = "";
            using (PexMeTermRewriter pexmeRewriter = new PexMeTermRewriter(tm))
            {
                fieldValue = pexmeRewriter.VisitTerm(default(TVoid), fieldValue); //update the field value to accomodate array-type field
                //if (indices.Length == 0) //not an array-type field
                if (indices.Length == 1) //is an array-type field
                {
                    arrayIndex = " at index of " + indices[0].UniqueIndex.ToString();
                }

                if(initialValue != null)
                    initialValue = pexmeRewriter.VisitTerm(default(TVoid), initialValue);
            }

            //Updating the method store
            MethodStore ms;
            if(!methodDic.TryGetValue(method, out ms))
            {
                ms = new MethodStore();
                ms.methodName = method;
                methodDic[method] = ms;
            }

            ms.WriteFields.Add(f);
            //TODO: Gather information of read fields

            //Updating the field store
            FieldStore fs;
            if (!fieldDic.TryGetValue(f, out fs))
            {
                fs = new FieldStore();
                fs.FieldName = f;
                fieldDic[f] = fs;
            }

            TypeEx declaringType;
            if (!method.TryGetDeclaringType(out declaringType))
            {
                this.Log.LogError(WikiTopics.MissingWikiTopic, "monitorfield",
                    "Failed to get the declaring type for the method " + method.FullName);
                return;
            }

            SafeSet<Method> writeMethods;
            if (!fs.WriteMethods.TryGetValue(declaringType, out writeMethods))
            {
                writeMethods = new SafeSet<Method>();
                fs.WriteMethods[declaringType] = writeMethods;
            }
            writeMethods.Add(method);

            var sb = new SafeStringBuilder();
            var swriter = new TermSExpWriter(tm, new SafeStringWriter(sb), true, false);
            swriter.Write(fieldValue);
            sb.Append(arrayIndex);

            int value;
            if (tm.TryGetI4Constant(fieldValue, out value))
            {
                int initialval;
                if (initialValue != null)
                    tm.TryGetI4Constant(initialValue, out initialval);
                else
                    initialval = 0;

                sb.Append("  constant value: " + value);

                if (f.Type.ToString() != "System.Boolean")
                {
                    if (value < initialval)
                        fs.ModificationTypeDictionary[method] = FieldModificationType.DECREMENT;
                    else if (value > initialval)
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.INCREMENT;

                        if (value == initialval + 1)
                            fs.PreciseModificationTypeDictionary[method] = FieldModificationType.INCREMENT_ONE;
                    }
                    else
                        fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;
                }
                else
                {
                    if (value == 0)
                        fs.ModificationTypeDictionary[method] = FieldModificationType.FALSE_SET;
                    else
                        fs.ModificationTypeDictionary[method] = FieldModificationType.TRUE_SET;
                }
            }
            else if (tm.IsDefaultValue(fieldValue))
            {
                if (initialValue != null && !tm.IsDefaultValue(initialValue))
                    fs.ModificationTypeDictionary[method] = FieldModificationType.NULL_SET;
                else
                    fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;

                sb.Append("  null reference ");
            }
            else
            {
                if (initialValue == null)
                    fs.ModificationTypeDictionary[method] = FieldModificationType.NON_NULL_SET;
                else
                    fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;

                sb.Append("  not-null reference ");
            }

            fs.FieldValues.Add(sb.ToString());
        }
        public static TypeEx AddFieldToMethodEffects(IPexComponent host, TypeEx declaringType, SafeSet<string> res, 
            SafeSet<string> directSetFields, SafeDictionary<string, FieldModificationType> modificationTypeDic,
            OpCode prevOpcode, Field field, TypeEx fieldType)
        {
            SafeDebug.AssumeNotNull(field, "field");
            SafeDebug.Assume(!field.IsStatic, "!field.IsStatic");

            TypeEx fieldDeclaringType;

            //The following check ensures that the field belongs to this class
            //or its base classes
            if (field.TryGetDeclaringType(out fieldDeclaringType) &&
                declaringType.IsAssignableTo(fieldDeclaringType))
            {
                res.Add(field.ShortName);

                FieldModificationType fmt = FieldModificationType.UNKNOWN;
                if (fieldType == SystemTypes.Int32 || fieldType == SystemTypes.Int64 || fieldType == SystemTypes.Int16)
                {
                    if (prevOpcode == OpCodes.Add)
                        fmt = FieldModificationType.INCREMENT;
                    else if (prevOpcode == OpCodes.Sub)
                        fmt = FieldModificationType.DECREMENT;
                    else if (prevOpcode == OpCodes.Call || prevOpcode == OpCodes.Calli || prevOpcode == OpCodes.Callvirt)
                        fmt = FieldModificationType.METHOD_CALL;
                    else
                        host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                "Encountered unknown modification type for integer type " + prevOpcode);
                }
                else
                {
                    if (field.Type.IsReferenceType)
                    {
                        if (prevOpcode == OpCodes.Ldnull)
                            fmt = FieldModificationType.NULL_SET;
                        else if (prevOpcode == OpCodes.Newarr || prevOpcode == OpCodes.Newobj)
                            fmt = FieldModificationType.NON_NULL_SET;
                        else if (LdArgOpCodes.Contains(prevOpcode))
                            fmt = FieldModificationType.NON_NULL_SET;
                        else
                        {
                            fmt = FieldModificationType.METHOD_CALL;    //A method call is invoked on this field, which updates this field
                        }
                    }
                    else if (fieldType == SystemTypes.Bool)
                    {
                        if (prevOpcode == OpCodes.Ldc_I4_0)
                            fmt = FieldModificationType.FALSE_SET;
                        else if (prevOpcode == OpCodes.Ldc_I4_1)
                            fmt = FieldModificationType.TRUE_SET;
                        else
                            host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                    "Encountered unknown modification type for boolean type " + prevOpcode);
                    }
                }

                //Store the value of fmt. Sometimes, the same field
                //can be modified in different ways within the method, for example
                //setting a boolean field to both true or false. In that case, the modification
                //type is left as unknown
                FieldModificationType prevFMT;
                if (modificationTypeDic.TryGetValue(field.ShortName, out prevFMT))
                {
                    //There is some entry for this field
                    if (prevFMT != FieldModificationType.UNKNOWN && prevFMT != fmt)
                    {
                        modificationTypeDic[field.ShortName] = FieldModificationType.UNKNOWN;
                    }
                }
                else
                {
                    modificationTypeDic[field.ShortName] = fmt;
                }

                //A heuristic based approach for aliasing analysis for checking whether the field is directly
                //assigned any parameters
                if (LdArgOpCodes.Contains(prevOpcode))
                    directSetFields.Add(field.ShortName);
            }
            return fieldDeclaringType;
        }
Beispiel #53
0
        /// <summary>
        /// Adds a monitored field to the database. Updates two kinds of hashmaps
        /// a. Field to Method mapper, which gives what the methods modifying a given field
        /// b. Method to Field mapper, which gives what fields are modified by each method (later used to identify a minimized set of methods)
        /// </summary>
        /// <param name="tm"></param>
        /// <param name="method"></param>
        /// <param name="f"></param>
        /// <param name="indices"></param>
        /// <param name="fieldValue"></param>
        public void AddMonitoredField(TermManager tm, Method method, Field f, Term[] indices, Term fieldValue, Term initialValue)
        {
            string arrayIndex = "";

            using (PexMeTermRewriter pexmeRewriter = new PexMeTermRewriter(tm))
            {
                fieldValue = pexmeRewriter.VisitTerm(default(TVoid), fieldValue); //update the field value to accomodate array-type field
                //if (indices.Length == 0) //not an array-type field
                if (indices.Length == 1)                                          //is an array-type field
                {
                    arrayIndex = " at index of " + indices[0].UniqueIndex.ToString();
                }

                if (initialValue != null)
                {
                    initialValue = pexmeRewriter.VisitTerm(default(TVoid), initialValue);
                }
            }

            //Updating the method store
            MethodStore ms;

            if (!methodDic.TryGetValue(method, out ms))
            {
                ms                = new MethodStore();
                ms.methodName     = method;
                methodDic[method] = ms;
            }

            ms.WriteFields.Add(f);
            //TODO: Gather information of read fields

            //Updating the field store
            FieldStore fs;

            if (!fieldDic.TryGetValue(f, out fs))
            {
                fs           = new FieldStore();
                fs.FieldName = f;
                fieldDic[f]  = fs;
            }

            TypeEx declaringType;

            if (!method.TryGetDeclaringType(out declaringType))
            {
                this.Log.LogError(WikiTopics.MissingWikiTopic, "monitorfield",
                                  "Failed to get the declaring type for the method " + method.FullName);
                return;
            }

            SafeSet <Method> writeMethods;

            if (!fs.WriteMethods.TryGetValue(declaringType, out writeMethods))
            {
                writeMethods = new SafeSet <Method>();
                fs.WriteMethods[declaringType] = writeMethods;
            }
            writeMethods.Add(method);

            var sb      = new SafeStringBuilder();
            var swriter = new TermSExpWriter(tm, new SafeStringWriter(sb), true, false);

            swriter.Write(fieldValue);
            sb.Append(arrayIndex);

            int value;

            if (tm.TryGetI4Constant(fieldValue, out value))
            {
                int initialval;
                if (initialValue != null)
                {
                    tm.TryGetI4Constant(initialValue, out initialval);
                }
                else
                {
                    initialval = 0;
                }

                sb.Append("  constant value: " + value);

                if (f.Type.ToString() != "System.Boolean")
                {
                    if (value < initialval)
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.DECREMENT;
                    }
                    else if (value > initialval)
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.INCREMENT;

                        if (value == initialval + 1)
                        {
                            fs.PreciseModificationTypeDictionary[method] = FieldModificationType.INCREMENT_ONE;
                        }
                    }
                    else
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;
                    }
                }
                else
                {
                    if (value == 0)
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.FALSE_SET;
                    }
                    else
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.TRUE_SET;
                    }
                }
            }
            else if (tm.IsDefaultValue(fieldValue))
            {
                if (initialValue != null && !tm.IsDefaultValue(initialValue))
                {
                    fs.ModificationTypeDictionary[method] = FieldModificationType.NULL_SET;
                }
                else
                {
                    fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;
                }

                sb.Append("  null reference ");
            }
            else
            {
                if (initialValue == null)
                {
                    fs.ModificationTypeDictionary[method] = FieldModificationType.NON_NULL_SET;
                }
                else
                {
                    fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;
                }

                sb.Append("  not-null reference ");
            }

            fs.FieldValues.Add(sb.ToString());
        }
        /// <summary>
        /// Populates all pair-wise combinations of defs and uses identified through static analysis
        /// </summary>
        public void PopulateDUCoverTable()
        {
            DUCoverStore dcs = DUCoverStore.GetInstance();

            SafeSet<FieldDefUseStore> allDefs = new SafeSet<FieldDefUseStore>();
            allDefs.AddRange(this.DefDic.Keys);
            allDefs.AddRange(this.DefOrUseSet);

            SafeSet<FieldDefUseStore> allUses = new SafeSet<FieldDefUseStore>();
            allUses.AddRange(this.UseDic.Keys);
            allUses.AddRange(this.DefOrUseSet);
            int numInfeasible = 0;

            //Compute pair-wise combinations
            foreach (var defEntry in allDefs)
            {
                foreach (var useEntry in allUses)
                {
                    //Ignore the trivial entries that involve just a combination of setter and getter methods
                    if (defEntry.Method.ShortName.StartsWith("set_") && useEntry.Method.ShortName.StartsWith("get_"))
                        continue;
                    if (!this.IsFeasibleDUCoverEntry(dcs, defEntry, useEntry))
                    {
                        numInfeasible++;
                        continue;
                    }

                    DUCoverStoreEntry dcse = new DUCoverStoreEntry(this.fd, defEntry.Method, defEntry.Offset,
                        useEntry.Method, useEntry.Offset);

                    if (defEntry.UnknownSideEffectMethod != null)
                    {
                        dcse.Def_UnknownSideEffectMethod = defEntry.UnknownSideEffectMethod;
                        dcse.DefUnsure = true;
                    }

                    if (useEntry.UnknownSideEffectMethod != null)
                    {
                        dcse.Use_UnknownSideEffectMethod = useEntry.UnknownSideEffectMethod;
                        dcse.UseUnsure = true;
                    }

                    if(!this.duCoverageTable.ContainsKey(dcse))
                        this.duCoverageTable[dcse] = 0;
                }
            }

            //Clear all the cached entries.
            this.feasibilityDicCache.Clear();

            logger.Debug("Detected infeasible du-pairs for field " + this.fd.FullName + "(" + numInfeasible + ")");
        }
Beispiel #55
0
        /// <summary>
        /// Helps guess factory methods for each uncovered condition
        /// </summary>
        private void GuessFactorymethods(out SafeSet <Method> allNewSuggestedPUTs, string currPUTSignature, out bool bHasSomeCoveredLocation,
                                         out bool bAllAreNewLocations, out bool bNoneAreNewLocations)
        {
            PexMeFactoryGuesser pfg = new PexMeFactoryGuesser(this.host);

            HashSet <string> allGivenUpLocations, allCoveredLocations, newUnCoveredLocations;

            //Analyze the current uncovered and previously uncovered locations
            this.pmd.AnalyzePreviousAndCurrentUncoveredLoc(currPUTSignature, out allGivenUpLocations,
                                                           out allCoveredLocations, out newUnCoveredLocations, out bHasSomeCoveredLocation, out bAllAreNewLocations, out bNoneAreNewLocations);

            allNewSuggestedPUTs = new SafeSet <Method>();
            //Iterate through each uncovered location
            foreach (var ucovLocList in pmd.UncoveredLocationDictionary.Values)
            {
                //TODO: Classify the uncovered locations into different groups
                //Because, it can happen that a single code location can have multiple terms which
                //cannot be merged together.
                if (ucovLocList.StoreList.Count == 0)
                {
                    continue;
                }

                //Check whether this location is earlier attempted and is failed. no
                //need to try this location again
                FactorySuggestionStore fss = null;
                string key = null;
                if (this.pmd.FactorySuggestionsDictionary.TryGetValue(ucovLocList.ExplorableType, out fss))
                {
                    key = UncoveredCodeLocationStore.GetKey(ucovLocList.Location.ToString(),
                                                            ucovLocList.ExplorableType, ucovLocList.TermIndex);

                    //A fix to keep track of uncovered locations in system libraries
                    if (TargetBranchAnalyzer.IsUncoveredLocationInSystemLib(ucovLocList.Location))
                    {
                        fss.UncoveredSystemLibLocations.Add(key);
                    }

                    if (allGivenUpLocations.Contains(key))
                    {
                        continue;
                    }
                    //Already covered locations can be reported again due to different PUTs or different call sites
                    //if (allCoveredLocations.Contains(key))
                    //    continue;
                    if (fss.PermanentFailedUncoveredLocations.Contains(key))
                    {
                        continue;
                    }
                    //if (fss.SuccessfulCoveredLocations.Contains(key))
                    //    continue;
                }

                //A single element of ucovLoc is sufficient here
                var ucovLoc = ucovLocList.StoreList[0];
                if (!pfg.TryInferFactoryMethod(ucovLoc, out ucovLoc.SuggestedMethodSetforFactory))
                {
                    this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "postprocessor",
                                             "Failed to suggest factory methods for uncovered location " + ucovLoc.ToString() + " -> Adding to permanent failed locations");

                    if (fss != null && key != null)
                    {
                        fss.PermanentFailedUncoveredLocations.Add(key);
                    }

                    continue;
                }

                //If a suggested method is not yet explored, add it to all new suggested method
                if (ucovLoc.SuggestedMethodSetforFactory != null)
                {
                    foreach (var suggestedm in ucovLoc.SuggestedMethodSetforFactory)
                    {
                        if (suggestedm.IsConstructor)
                        {
                            continue;
                        }

                        //Check if this is ever explored by this process by getting associated PUT
                        Method pexmethod;
                        bool   bretval = PUTGenerator.PUTGenerator.TryRetrievePUT(this.pmd, this.currAssembly, suggestedm, out pexmethod);
                        if (!bretval)
                        {
                            //The suggested method is out of scope of current library and
                            //no need to explore it explicitly
                            continue;
                        }

                        //Ignore self suggestions
                        if (pexmethod == this.pmd.CurrentPUTMethod)
                        {
                            continue;
                        }
                        var signature = MethodOrFieldAnalyzer.GetMethodSignature(pexmethod);
                        if (this.pmd.AllExploredMethods.Contains(signature))
                        {
                            continue;
                        }

                        if (this.pmd.PendingExplorationMethods.Contains(signature))
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic,
                                                     "Nested PUTs", "Ignoring the nested PUT due to cycle detection " + signature);
                            continue;
                        }

                        allNewSuggestedPUTs.Add(pexmethod);
                    }
                }
            }
        }
        public static TypeEx AddFieldToMethodEffects(IPexComponent host, TypeEx declaringType, SafeSet <string> res,
                                                     SafeSet <string> directSetFields, SafeDictionary <string, FieldModificationType> modificationTypeDic,
                                                     OpCode prevOpcode, Field field, TypeEx fieldType)
        {
            SafeDebug.AssumeNotNull(field, "field");
            SafeDebug.Assume(!field.IsStatic, "!field.IsStatic");

            TypeEx fieldDeclaringType;

            //The following check ensures that the field belongs to this class
            //or its base classes
            if (field.TryGetDeclaringType(out fieldDeclaringType) &&
                declaringType.IsAssignableTo(fieldDeclaringType))
            {
                res.Add(field.ShortName);

                FieldModificationType fmt = FieldModificationType.UNKNOWN;
                if (fieldType == SystemTypes.Int32 || fieldType == SystemTypes.Int64 || fieldType == SystemTypes.Int16)
                {
                    if (prevOpcode == OpCodes.Add)
                    {
                        fmt = FieldModificationType.INCREMENT;
                    }
                    else if (prevOpcode == OpCodes.Sub)
                    {
                        fmt = FieldModificationType.DECREMENT;
                    }
                    else if (prevOpcode == OpCodes.Call || prevOpcode == OpCodes.Calli || prevOpcode == OpCodes.Callvirt)
                    {
                        fmt = FieldModificationType.METHOD_CALL;
                    }
                    else
                    {
                        host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                            "Encountered unknown modification type for integer type " + prevOpcode);
                    }
                }
                else
                {
                    if (field.Type.IsReferenceType)
                    {
                        if (prevOpcode == OpCodes.Ldnull)
                        {
                            fmt = FieldModificationType.NULL_SET;
                        }
                        else if (prevOpcode == OpCodes.Newarr || prevOpcode == OpCodes.Newobj)
                        {
                            fmt = FieldModificationType.NON_NULL_SET;
                        }
                        else if (LdArgOpCodes.Contains(prevOpcode))
                        {
                            fmt = FieldModificationType.NON_NULL_SET;
                        }
                        else
                        {
                            fmt = FieldModificationType.METHOD_CALL;    //A method call is invoked on this field, which updates this field
                        }
                    }
                    else if (fieldType == SystemTypes.Bool)
                    {
                        if (prevOpcode == OpCodes.Ldc_I4_0)
                        {
                            fmt = FieldModificationType.FALSE_SET;
                        }
                        else if (prevOpcode == OpCodes.Ldc_I4_1)
                        {
                            fmt = FieldModificationType.TRUE_SET;
                        }
                        else
                        {
                            host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                                "Encountered unknown modification type for boolean type " + prevOpcode);
                        }
                    }
                }

                //Store the value of fmt. Sometimes, the same field
                //can be modified in different ways within the method, for example
                //setting a boolean field to both true or false. In that case, the modification
                //type is left as unknown
                FieldModificationType prevFMT;
                if (modificationTypeDic.TryGetValue(field.ShortName, out prevFMT))
                {
                    //There is some entry for this field
                    if (prevFMT != FieldModificationType.UNKNOWN && prevFMT != fmt)
                    {
                        modificationTypeDic[field.ShortName] = FieldModificationType.UNKNOWN;
                    }
                }
                else
                {
                    modificationTypeDic[field.ShortName] = fmt;
                }


                //A heuristic based approach for aliasing analysis for checking whether the field is directly
                //assigned any parameters
                if (LdArgOpCodes.Contains(prevOpcode))
                {
                    directSetFields.Add(field.ShortName);
                }
            }
            return(fieldDeclaringType);
        }
        /// <summary>
        /// Removes if there are any infeasible definitions
        /// </summary>
        private void RemoveInfeasibleDefs(DUCoverStore dcs)
        {
            //There are either zero or one definitions
            if (this.defDic.Count <= 1)
                return;

            SafeSet<FieldDefUseStore> infeasibleDefs = new SafeSet<FieldDefUseStore>();
            foreach (var fdef in this.defDic.Keys)
            {
                var otherFDefOffsets = this.GetOtherDefOffsetsInMethod(fdef.Method, fdef);
                if (otherFDefOffsets.Count == 0)
                    continue;

                if (HasRedefinition(dcs, fdef, otherFDefOffsets))
                    infeasibleDefs.Add(fdef);
            }
            this.defDic.RemoveRange(infeasibleDefs);
        }