Example #1
0
        private static bool GetNewRulesAndPrepareContext(out FaultRule[] newRules, string currentFunction)
        {
            try
            {
                newRules = FaultRuleLoader.Load();
            }
            catch (FaultInjectionException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new FaultInjectionException(FaultDispatcherMessages.LoadFaultRuleError, e);
            }
            if (newRules == null || newRules.Length == 0)
            {
                return(false);
            }

            lock (initialized)
            {
                if (contexts == null)
                {
                    int length = newRules.Length;
                    contexts = new RuntimeContext[length];
                    for (int i = 0; i < length; ++i)
                    {
                        contexts[i] = new RuntimeContext();
                    }
                }
            }

            return(true);
        }
Example #2
0
        /// <summary>
        /// Checks that
        /// </summary>
        public void AssertFaultInjectionEnabled()
        {
            StringBuilder errors = new StringBuilder();

            // Verify registry
            if (!ComRegistrar.IsRegistered())
            {
                errors.AppendLine(ApiErrorMessages.EngineNotRegistered);
            }

            // Verify profiler environment variables.
            // Is "COMPLUS_ProfAPI_ProfilerCompatibilitySetting=EnableV2Profiler" still needed?
            if (Environment.GetEnvironmentVariable(EnvironmentVariable.EnableProfiling) != "1")
            {
                errors.AppendLine(ApiErrorMessages.ProfilerNotEnabled);
            }

            string profiler = Environment.GetEnvironmentVariable(EnvironmentVariable.Profiler);

            if (profiler != EngineInfo.Engine_CLSID)
            {
                errors.AppendLine(string.Format(ApiErrorMessages.ProfilerNotSpecified, profiler));
            }

            if (Environment.GetEnvironmentVariable(EnvironmentVariable.ProfilerCompatibilityForCLR4) !=
                EnvironmentVariable.EnableV2Profiler)
            {
                errors.AppendLine(ApiErrorMessages.ProfilerV2CompatibilityNotSpecified);
            }

            // Verify log directory
            string logDirectory = Environment.GetEnvironmentVariable(EnvironmentVariable.LogDirectory);

            if (String.IsNullOrEmpty(logDirectory) || logDirectory.Trim().Length == 0)
            {
                errors.AppendLine(ApiErrorMessages.LogDirectoryNotSet);
            }
            else if (!Directory.Exists(logDirectory))
            {
                errors.AppendLine(string.Format(ApiErrorMessages.LogDirectoryAccessDenied, logDirectory));
            }

            // Verify that fault rules can be loaded
            FaultRule[] rules = FaultRuleLoader.Load();
            if (rules == null)
            {
                errors.AppendLine(ApiErrorMessages.NoFaultRulesLoaded);
            }

            // Verify that the method filter file exists
            string methodFilterFileName = Environment.GetEnvironmentVariable(EnvironmentVariable.MethodFilter);

            if (string.IsNullOrEmpty(methodFilterFileName))
            {
                errors.AppendLine(ApiErrorMessages.MethodFilterFileNotSet);
            }
            else
            {
                StreamReader methodFilterFile = null;
                try
                {
                    // Verify that the method filter file contains an entry for every method that has a fault rule
                    methodFilterFile = File.OpenText(methodFilterFileName);
                    List <string> methodFilterContents = new List <string>();
                    while (!methodFilterFile.EndOfStream)
                    {
                        methodFilterContents.Add(methodFilterFile.ReadLine().Trim());
                    }

                    bool allEntriesFound = true;
                    foreach (FaultRule r in rules)
                    {
                        string comSignature = Signature.ConvertSignature(r.MethodSignature, SignatureStyle.Com);
                        if (!methodFilterContents.Any(s => s == comSignature))
                        {
                            allEntriesFound = false;
                            errors.AppendLine(
                                string.Format(ApiErrorMessages.MethodFilterFileHasMissingEntry,
                                              Environment.GetEnvironmentVariable(EnvironmentVariable.MethodFilter),
                                              r.MethodSignature,
                                              comSignature));
                        }
                    }
                    if (!allEntriesFound)
                    {
                        errors.AppendLine(string.Format(ApiErrorMessages.MethodFilterFileContentsDump, methodFilterFileName));
                        foreach (string s in methodFilterContents)
                        {
                            errors.AppendLine(s);
                        }
                    }
                }
                catch (IOException e)
                {
                    if (methodFilterFile != null)
                    {
                        methodFilterFile.Dispose();
                    }
                    errors.AppendLine(string.Format(ApiErrorMessages.MethodFilterFileAccessDenied, methodFilterFileName));
                    errors.Append("\t");
                    errors.AppendLine(e.Message);
                }
            }

            // Verify FaultDispatcher.Trap() method exists and can be loaded by the current runtime
            FaultDispatcherDelegate t = FaultDispatcher.Trap;

            // Verify FaultDispatcher assembly has the public key token that the engine expects
            string faultDispatcherAssemblyName = typeof(FaultDispatcher).Assembly.FullName;

            if (!faultDispatcherAssemblyName.Contains(EngineInfo.FaultDispatcherAssemblyPublicKeyToken))
            {
                errors.AppendLine(string.Format(ApiErrorMessages.FaultDispatcherCannotBeLoaded, faultDispatcherAssemblyName));
            }

            // Now throw the errors if they exist
            if (errors.Length != 0)
            {
                throw new FaultInjectionException(errors.ToString());
            }
        }
Example #3
0
        /// <summary>
        /// Injected into the prologue of the target method.
        /// </summary>
        /// <param name="exceptionValue">Exception thrown by fault</param>
        /// <param name="returnValue">Value to return from fault</param>
        /// <returns></returns>
        /// <remarks>
        /// Trap creates a RuntimeContext for the current call and evaluates
        /// the fault condition's Trigger method.  If it evaluates to true
        /// the fault's Retrieve method is called.
        /// </remarks>
        public static bool Trap(out Exception exceptionValue, out Object returnValue)
        {
            exceptionValue = null;
            returnValue    = null;
            FaultRule[] newRules;
            try
            {
                newRules = FaultRuleLoader.Load();
            }
            catch (Exception e)
            {
                throw new FaultInjectionException(FaultDispatcherMessages.LoadFaultRuleError, e);
            }

            if (newRules == null || newRules.Length == 0)
            {
                return(false);
            }

            StackTrace stackTrace = new StackTrace(1);
            CallStack  callStack  = new CallStack(stackTrace);
            //stackFrame does not include Trap()
            StackFrame stackFrame      = stackTrace.GetFrame(0);
            String     currentFunction = callStack[0];

            RuntimeContext currentContext = null;
            FaultRule      rule           = null;

            try
            {
                //Get Fault Rule and Update current RuntimeContext
                int len = newRules.Length;
                for (int i = 0; i < len; ++i)
                {
                    if (newRules[i].FormalSignature != null &&
                        currentFunction.Equals(newRules[i].FormalSignature) == true)
                    {
                        rule                          = newRules[i];
                        currentContext                = new RuntimeContext();
                        currentContext.CalledTimes    = rule.IncrementAndReturnNumTimesCalled();
                        currentContext.CallStack      = callStack;
                        currentContext.CallStackTrace = stackTrace;

                        break;
                    }
                }

                //Using ICondition and IFault
                if (rule == null)
                {
                    return(false);
                }
                bool triggered = false;
                try
                {
                    triggered = rule.Condition.Trigger(currentContext);
                    if (triggered == true)
                    {
                        rule.Fault.Retrieve(currentContext, out (exceptionValue), out returnValue);
                    }
                }
                catch (System.Exception e)
                {
                    throw new FaultInjectionException(FaultDispatcherMessages.NoExceptionAllowedInTriggerAndRetrieve, e);
                }
                if (!triggered)
                {
                    return(false);
                }
            }
            catch (System.Exception e)
            {
                throw new FaultInjectionException(FaultDispatcherMessages.UnknownExceptionInTrap, e);
            }


            // check return-value's type if not to throw exception
            if (null == exceptionValue)
            {
                if (stackFrame.GetMethod() is ConstructorInfo)
                {
                    return(true);
                }
                Type returnTypeOfTrappedMethod = ((MethodInfo)stackFrame.GetMethod()).ReturnType;
                return(CheckReturnType(returnTypeOfTrappedMethod, returnValue, currentFunction));
            }
            return(true);
        }