示例#1
0
        /// <summary>
        /// Gets a persistent location store version of an uncovered location store
        /// </summary>
        /// <param name="ucls"></param>
        /// <returns></returns>
        public PersistentUncoveredLocationStore GetPersistentLocationstore(UncoveredCodeLocationStore ucls,
                                                                           out bool bNewlyCreated)
        {
            PersistentUncoveredLocationStore pucls;

            bNewlyCreated = false;
            var key = UncoveredCodeLocationStore.GetKey(ucls.Location.ToString(), ucls.ExplorableType.ToString(), ucls.TermIndex);

            if (!locationStoreSpecificSequences.TryGetValue(key, out pucls))
            {
                pucls = new PersistentUncoveredLocationStore(ucls.Location, ucls.ExplorableType,
                                                             ucls.TermIndex, ucls.Fitnessvalue, this);
                pucls.CodeLocation = ucls.Location.ToString();
                locationStoreSpecificSequences[key] = pucls;
                bNewlyCreated = true;
            }
            return(pucls);
        }
        /// <summary>
        /// Removes the uncovered location store. Mainly keeps the sequence
        /// that helped to cover the target location and drops all others       
        /// </summary>
        /// <param name="pucls"></param>
        /// <param name="successful">Helps to distinguish between a removal during success and failure</param>
        internal void RemoveUncoveredLocationStore(PersistentUncoveredLocationStore pucls, 
            bool successful, PexMeDynamicDatabase pmd)
        {
            var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation, pucls.ExplorableType, pucls.TermIndex);
            this.locationStoreSpecificSequences.Remove(key);
            if (!successful)
            {
                return;
            }

            this.SuccessfulCoveredLocations.Add(key);
            this.PermanentFailedUncoveredLocations.Remove(key);
            this.TemporaryFailedUncoveredLocations.Remove(key);
            this.UncoveredSystemLibLocations.Remove(key);

            //Get the method associated with the current exploring PUT
            string methodcallname = PexMeConstants.DEFAULT_FINAL_SUGGESTION_STORE;
            Method assocMethod;
            if (PUTGenerator.PUTGenerator.TryRetrieveMethodCall(pmd.CurrentPUTMethod, out assocMethod))
                methodcallname = MethodOrFieldAnalyzer.GetMethodSignature(assocMethod);

            //Get PUT independent sequence list
            MethodSignatureSequenceList putIndependentMssl;
            if (!this.FinalSuggestedMethodSequences.TryGetValue(methodcallname, out putIndependentMssl))
            {
                putIndependentMssl = new MethodSignatureSequenceList();
                this.FinalSuggestedMethodSequences.Add(methodcallname, putIndependentMssl);
            }

            //Also update the PUT specific sequences. These gets cleared once a
            //PUT is completely explored.
            var putsignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod);
            MethodSignatureSequenceList putSpecificMssl;
            if (!this.FinalPUTSequences.TryGetValue(putsignature, out putSpecificMssl))
            {
                putSpecificMssl = new MethodSignatureSequenceList();
                this.FinalPUTSequences.Add(putsignature, putSpecificMssl);
            }

            //Any Persistent Uncovered location store that is successfully
            //covered gets a hit sequence
            SafeDebug.AssumeNotNull(pucls.HitSequence, "pucls.HitSequence");
            MethodSignatureSequence matchingseq;
            if (!FactorySuggestionStore.TryGetMatchingSequence(pucls.HitSequence,
                pucls.SuggestedMethodSequences, out matchingseq))
            {
                //Failed to retrieve the hit sequence. However, a heuristic
                //can be used where there is only one suggested sequence
                if (pucls.SuggestedMethodSequences.Count == 1)
                {
                    matchingseq = pucls.SuggestedMethodSequences[0];
                    putIndependentMssl.Add(matchingseq);
                    putSpecificMssl.Add(matchingseq);
                }
                else
                {
                    pmd.Log.LogWarning(WikiTopics.MissingWikiTopic, "SequenceMatch",
                        "Failed to retrieve a matching sequence for a hit sequence, adding complete hit sequence " + pucls.HitSequence);

                    var hitSubSequence = new MethodSignatureSequence();
                    foreach (var mhit in pucls.HitSequence.Sequence)
                    {
                        if (mhit.Contains("..ctor(")) //Don't add constructors
                            continue;
                        if (!mhit.Contains(this.DeclaringType)) //Ignore the method calls from other types
                            continue;
                        hitSubSequence.Sequence.Add(mhit);
                    }

                    //Add all sequences to final set of sequences for further usage.
                    putIndependentMssl.Add(hitSubSequence);
                    putSpecificMssl.Add(hitSubSequence);
                    //this.UpgradeActiveULStores(putsignature, pucls.SuggestedMethodSequences);
                }
            }
            else
            {
                //Add all sequences to final set of sequences for further usage.
                putIndependentMssl.Add(matchingseq);
                putSpecificMssl.Add(matchingseq);
                //this.UpgradeActiveULStores(putsignature, matchingseq);
            }
        }
 /// <summary>
 /// Gets a persistent location store version of an uncovered location store
 /// </summary>
 /// <param name="ucls"></param>
 /// <returns></returns>
 public PersistentUncoveredLocationStore GetPersistentLocationstore(UncoveredCodeLocationStore ucls,
     out bool bNewlyCreated)
 {
     PersistentUncoveredLocationStore pucls;
     bNewlyCreated = false;
     var key = UncoveredCodeLocationStore.GetKey(ucls.Location.ToString(), ucls.ExplorableType.ToString(), ucls.TermIndex);
     if (!locationStoreSpecificSequences.TryGetValue(key, out pucls))
     {
         pucls = new PersistentUncoveredLocationStore(ucls.Location, ucls.ExplorableType,
             ucls.TermIndex, ucls.Fitnessvalue, this);
         pucls.CodeLocation = ucls.Location.ToString();
         locationStoreSpecificSequences[key] = pucls;
         bNewlyCreated = true;
     }
     return pucls;
 }
示例#4
0
        /// <summary>
        /// Removes the uncovered location store. Mainly keeps the sequence
        /// that helped to cover the target location and drops all others
        /// </summary>
        /// <param name="pucls"></param>
        /// <param name="successful">Helps to distinguish between a removal during success and failure</param>
        internal void RemoveUncoveredLocationStore(PersistentUncoveredLocationStore pucls,
                                                   bool successful, PexMeDynamicDatabase pmd)
        {
            var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation, pucls.ExplorableType, pucls.TermIndex);

            this.locationStoreSpecificSequences.Remove(key);
            if (!successful)
            {
                return;
            }

            this.SuccessfulCoveredLocations.Add(key);
            this.PermanentFailedUncoveredLocations.Remove(key);
            this.TemporaryFailedUncoveredLocations.Remove(key);
            this.UncoveredSystemLibLocations.Remove(key);

            //Get the method associated with the current exploring PUT
            string methodcallname = PexMeConstants.DEFAULT_FINAL_SUGGESTION_STORE;
            Method assocMethod;

            if (PUTGenerator.PUTGenerator.TryRetrieveMethodCall(pmd.CurrentPUTMethod, out assocMethod))
            {
                methodcallname = MethodOrFieldAnalyzer.GetMethodSignature(assocMethod);
            }

            //Get PUT independent sequence list
            MethodSignatureSequenceList putIndependentMssl;

            if (!this.FinalSuggestedMethodSequences.TryGetValue(methodcallname, out putIndependentMssl))
            {
                putIndependentMssl = new MethodSignatureSequenceList();
                this.FinalSuggestedMethodSequences.Add(methodcallname, putIndependentMssl);
            }

            //Also update the PUT specific sequences. These gets cleared once a
            //PUT is completely explored.
            var putsignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod);
            MethodSignatureSequenceList putSpecificMssl;

            if (!this.FinalPUTSequences.TryGetValue(putsignature, out putSpecificMssl))
            {
                putSpecificMssl = new MethodSignatureSequenceList();
                this.FinalPUTSequences.Add(putsignature, putSpecificMssl);
            }

            //Any Persistent Uncovered location store that is successfully
            //covered gets a hit sequence
            SafeDebug.AssumeNotNull(pucls.HitSequence, "pucls.HitSequence");
            MethodSignatureSequence matchingseq;

            if (!FactorySuggestionStore.TryGetMatchingSequence(pucls.HitSequence,
                                                               pucls.SuggestedMethodSequences, out matchingseq))
            {
                //Failed to retrieve the hit sequence. However, a heuristic
                //can be used where there is only one suggested sequence
                if (pucls.SuggestedMethodSequences.Count == 1)
                {
                    matchingseq = pucls.SuggestedMethodSequences[0];
                    putIndependentMssl.Add(matchingseq);
                    putSpecificMssl.Add(matchingseq);
                }
                else
                {
                    pmd.Log.LogWarning(WikiTopics.MissingWikiTopic, "SequenceMatch",
                                       "Failed to retrieve a matching sequence for a hit sequence, adding complete hit sequence " + pucls.HitSequence);

                    var hitSubSequence = new MethodSignatureSequence();
                    foreach (var mhit in pucls.HitSequence.Sequence)
                    {
                        if (mhit.Contains("..ctor(")) //Don't add constructors
                        {
                            continue;
                        }
                        if (!mhit.Contains(this.DeclaringType)) //Ignore the method calls from other types
                        {
                            continue;
                        }
                        hitSubSequence.Sequence.Add(mhit);
                    }

                    //Add all sequences to final set of sequences for further usage.
                    putIndependentMssl.Add(hitSubSequence);
                    putSpecificMssl.Add(hitSubSequence);
                    //this.UpgradeActiveULStores(putsignature, pucls.SuggestedMethodSequences);
                }
            }
            else
            {
                //Add all sequences to final set of sequences for further usage.
                putIndependentMssl.Add(matchingseq);
                putSpecificMssl.Add(matchingseq);
                //this.UpgradeActiveULStores(putsignature, matchingseq);
            }
        }
        /// <summary>
        /// Checks whether there are any looping requireements based on looping threshold and enhances 
        /// the sequence accordingly. Applies only for INCREMENT and DECREMENT field modification types
        /// </summary>
        /// <param name="pucls"></param>
        /// <param name="p"></param>
        private void CheckNEnhanceForLooping(PersistentUncoveredLocationStore pucls, 
            int fitnessval, FieldModificationType fmt, SafeList<Field> culpritFields)
        {
            if (fmt != FieldModificationType.INCREMENT && fmt != FieldModificationType.DECREMENT)
                return;

            //Not even a single execution happened on this location.
            if (fitnessval == Int32.MaxValue)
                return;

            var field = culpritFields[0];
            FieldStore fs;
            if (!this.pmd.FieldDictionary.TryGetValue(field, out fs))
                return;

            Dictionary<string, Method> writeMethods = new Dictionary<string, Method>();
            foreach (var mset in fs.WriteMethods.Values)
            {
                foreach (var m in mset)
                {
                    var sig = MethodOrFieldAnalyzer.GetMethodSignature(m);
                    writeMethods.Add(sig, m);
                }
            }

            foreach (var seq in pucls.SuggestedMethodSequences)
            {
                string loop_method;
                if (!this.IsEligibleForLooping(seq, field, writeMethods, fs, out loop_method))
                    continue;

                pucls.LoopingFeatureApplied = true;
                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "LoopingFeature",
                    "Applying looping feature on method: " + loop_method + " (" + (fitnessval - 1) + ")");
                for (int count = 1; count < fitnessval; count++)
                    seq.Sequence.Add(loop_method);
            }
        }
        /// <summary>
        /// Check whether a previously uncovered location is covered now in this run
        /// </summary>
        public bool IsPrevUncoveredLocationCovered(PersistentUncoveredLocationStore pucls)
        {
            //retrieve the method
            MethodDefinition associatedMethod;
            if (!MethodOrFieldAnalyzer.TryGetMethodDefinition(this, pucls.AssemblyShortName, pucls.declaringTypeStr,
                pucls.MethodSignature, out associatedMethod))
            {
                this.Log.LogWarning(WikiTopics.MissingWikiTopic, "serialization",
                    "Failed to retrieve the method with signature " + pucls.MethodSignature);
                return false;
            }

            //Check whether the offset is covered in this method
            if (this.IsBranchOffsetCoveredInMethod(associatedMethod, pucls.Offset))
                return true;

            return false;
        }
        /// <summary>
        /// Targets to remove those sequences with low or the same fitness
        /// </summary>
        /// <param name="ucovLocList"></param>
        /// <param name="persistentUncoveredLocationStore"></param>
        private void RemoveSuggestionsWithLowFitness(UncoveredCodeLocationStoreList ucovLocList, 
            PersistentUncoveredLocationStore pucls, List<MethodSignatureSequence> putspecificsequences)
        {
            pucls.NumberOfUnsuccessfulAttempts++;
            int bestFitness = pucls.Fitnessvalue;

            foreach (var ucovloc in ucovLocList.StoreList)
            {
                if (ucovloc.Fitnessvalue < bestFitness)
                    bestFitness = ucovloc.Fitnessvalue;
            }

            var explorableType = ucovLocList.ExplorableType;
            var tempSuggestedSequences = new List<MethodSignatureSequence>();
            tempSuggestedSequences.AddRange(pucls.SuggestedMethodSequences);

            //remove those suggestions that have lower fitness values
            foreach (var ucovloc in ucovLocList.StoreList)
            {
                //Get matching sequence from pucls
                MethodSignatureSequence matchingseq;
                if (!FactorySuggestionStore.TryGetMatchingSequence(ucovloc.MethodCallSequence, tempSuggestedSequences, out matchingseq))
                {
                    //This sequence is not there in our suggested sequence. This should have happened
                    //due to the case that it came from other uncovered location stores, and is helping
                    //the current store.
                    if (ucovloc.Fitnessvalue <= bestFitness)
                    {
                        var mss = new MethodSignatureSequence();
                        foreach (var methodinucov in ucovloc.MethodCallSequence.Sequence)
                        {
                            if (methodinucov.Contains("..ctor(")) //Don't add constructors
                                continue;
                            if (!methodinucov.Contains(explorableType)) //Ignore the method calls from other types
                                continue;
                            mss.Sequence.Add(methodinucov);
                        }

                        if(mss.Sequence.Count > 0)
                            pucls.SuggestedMethodSequences.Add(mss);
                    }

                    continue;
                }

                tempSuggestedSequences.Remove(matchingseq);
                if (ucovloc.Fitnessvalue > bestFitness)
                {
                    //Previous sequence is of no use as it is leading to higher fitness value
                    pucls.SuggestedMethodSequences.Remove(matchingseq);
                }
            }

            if (tempSuggestedSequences.Count != 0)
            {
                //Not all sequences are assigned fitness values. Raise warnings for other sequences
                this.Log.LogWarning(WikiTopics.MissingWikiTopic, "sequencematching",
                    "Fitness values are not available for some previous sequences, Needs to handle this case!!!");

                //Remove those suggestions whose fitness value is not evaluated at all. Ideally
                //this case should not happen. Needs additional debugging.
                //foreach (var seq in tempSuggestedSequences)
                //    pucls.SuggestedMethodSequences.Remove(seq);
            }

            //Update the previous fitness value with the current. If there is any improvement in the fitness, reset the number
            //of unsuccessful attempts
            if (pucls.Fitnessvalue != bestFitness)
            {
                pucls.NumberOfUnsuccessfulAttempts = 0;
                pucls.Fitnessvalue = bestFitness;
            }
        }