Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Diagnostics / Contracts / ContractsBCL.cs / 1305376 / ContractsBCL.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: Contract ** **maf,mbarnett,[....] ** ** Implementation details of CLR Contracts. ** ===========================================================*/ #define DEBUG // The behavior of this contract library should be consistent regardless of build type. #if SILVERLIGHT #define FEATURE_UNTRUSTED_CALLERS #elif REDHAWK_RUNTIME #elif BARTOK_RUNTIME #else // CLR #define FEATURE_UNTRUSTED_CALLERS #define FEATURE_RELIABILITY_CONTRACTS #define FEATURE_SERIALIZATION #endif using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; #if FEATURE_RELIABILITY_CONTRACTS using System.Runtime.ConstrainedExecution; #endif #if FEATURE_UNTRUSTED_CALLERS using System.Security; using System.Security.Permissions; #endif namespace System.Diagnostics.Contracts { public static partial class Contract { #region Private Methods private static bool _assertingMustUseRewriter; ////// This method is used internally to trigger a failure indicating to the "programmer" that he is using the interface incorrectly. /// It is NEVER used to indicate failure of actual contracts at runtime. /// static partial void AssertMustUseRewriter(ContractFailureKind kind, String contractKind) { if (_assertingMustUseRewriter) System.Diagnostics.Assert.Fail("Asserting that we must use the rewriter went reentrant.", "Didn't rewrite this mscorlib?"); _assertingMustUseRewriter = true; // @ Internal.ContractHelper.TriggerFailure(kind, "Must use the rewriter when using Contract." + contractKind, null, null, null); _assertingMustUseRewriter = false; } #endregion Private Methods #region Failure Behavior ////// Without contract rewriting, failing Assert/Assumes end up calling this method. /// Code going through the contract rewriter never calls this method. Instead, the rewriter produced failures call /// Internal.ContractHelper.RaiseContractFailedEvent, followed by Internal.ContractHelper.TriggerFailure. /// [SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Security.SecuritySafeCriticalAttribute")] #if FEATURE_UNTRUSTED_CALLERS [SecuritySafeCritical] #endif [System.Diagnostics.DebuggerNonUserCode] #if FEATURE_RELIABILITY_CONTRACTS [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] #endif static partial void ReportFailure(ContractFailureKind failureKind, String userMessage, String conditionText, Exception innerException) { if (failureKind < ContractFailureKind.Precondition || failureKind > ContractFailureKind.Assume) throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", failureKind), "failureKind"); Contract.EndContractBlock(); // displayMessage == null means: yes we handled it. Otherwise it is the localized failure message var displayMessage = Internal.ContractHelper.RaiseContractFailedEvent(failureKind, userMessage, conditionText, innerException); if (displayMessage == null) return; Internal.ContractHelper.TriggerFailure(failureKind, displayMessage, userMessage, conditionText, innerException); } ////// Allows a managed application environment such as an interactive interpreter (IronPython) or a /// web browser host (Jolt hosting Silverlight in IE) to be notified of contract failures and /// potentially "handle" them, either by throwing a particular exception type, etc. If any of the /// event handlers sets the Cancel flag in the ContractFailedEventArgs, then the Contract class will /// not pop up an assert dialog box or trigger escalation policy. Hooking this event requires /// full trust. /// public static event EventHandlerContractFailed { #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #if FEATURE_LINK_DEMAND [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] #endif #endif add { Internal.ContractHelper.InternalContractFailed += value; } #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #if FEATURE_LINK_DEMAND [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] #endif #endif remove { Internal.ContractHelper.InternalContractFailed -= value; } } #endregion FailureBehavior } public sealed class ContractFailedEventArgs : EventArgs { private ContractFailureKind _failureKind; private String _message; private String _condition; private Exception _originalException; private bool _handled; private bool _unwind; internal Exception thrownDuringHandler; #if FEATURE_RELIABILITY_CONTRACTS [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] #endif public ContractFailedEventArgs(ContractFailureKind failureKind, String message, String condition, Exception originalException) { Contract.Requires(originalException == null || failureKind == ContractFailureKind.PostconditionOnException); _failureKind = failureKind; _message = message; _condition = condition; _originalException = originalException; } public String Message { get { return _message; } } public String Condition { get { return _condition; } } public ContractFailureKind FailureKind { get { return _failureKind; } } public Exception OriginalException { get { return _originalException; } } // Whether the event handler "handles" this contract failure, or to fail via escalation policy. public bool Handled { get { return _handled; } } #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #if FEATURE_LINK_DEMAND [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] #endif #endif public void SetHandled() { _handled = true; } public bool Unwind { get { return _unwind; } } #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #if FEATURE_LINK_DEMAND [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] #endif #endif public void SetUnwind() { _unwind = true; } } #if FEATURE_SERIALIZATION [Serializable] #else [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors")] #endif [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")] internal sealed class ContractException : Exception { readonly ContractFailureKind _Kind; readonly string _UserMessage; readonly string _Condition; [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public ContractFailureKind Kind { get { return _Kind; } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string Failure { get { return this.Message; } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string UserMessage { get { return _UserMessage; } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string Condition { get { return _Condition; } } public ContractException() { } #if false public ContractException(string msg) : base(msg) { _Kind = ContractFailureKind.Precondition; } public ContractException(string msg, Exception inner) : base(msg, inner) { } #endif public ContractException(ContractFailureKind kind, string failure, string userMessage, string condition, Exception innerException) : base(failure, innerException) { this._Kind = kind; this._UserMessage = userMessage; this._Condition = condition; } #if FEATURE_SERIALIZATION private ContractException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { _Kind = (ContractFailureKind)info.GetInt32("Kind"); _UserMessage = info.GetString("UserMessage"); _Condition = info.GetString("Condition"); } #endif // FEATURE_SERIALIZATION [System.Runtime.InteropServices.ComVisible(false)] // Hack: This is not necessary, but the BCL's TrimSrc tool // for createBclSmall needs ANY attribute to correctly parse this file. #ifdefs are treated // as whitespace - they're occasionally preserved. #if FEATURE_UNTRUSTED_CALLERS && FEATURE_SERIALIZATION [SecurityCritical] #if FEATURE_LINK_DEMAND && FEATURE_SERIALIZATION [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] #endif // FEATURE_LINK_DEMAND #endif // FEATURE_UNTRUSTED_CALLERS public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { base.GetObjectData(info, context); info.AddValue("Kind", _Kind); info.AddValue("UserMessage", _UserMessage); info.AddValue("Condition", _Condition); } } } namespace System.Diagnostics.Contracts.Internal { public static partial class ContractHelper { #region Private fields private static EventHandler contractFailedEvent; private static readonly Object lockObject = new Object(); #endregion /// /// Allows a managed application environment such as an interactive interpreter (IronPython) or a /// web browser host (Jolt hosting Silverlight in IE) to be notified of contract failures and /// potentially "handle" them, either by throwing a particular exception type, etc. If any of the /// event handlers sets the Cancel flag in the ContractFailedEventArgs, then the Contract class will /// not pop up an assert dialog box or trigger escalation policy. Hooking this event requires /// full trust. /// internal static event EventHandlerInternalContractFailed { #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #endif add { // Eagerly prepare each event handler _marked with a reliability contract_, to // attempt to reduce out of memory exceptions while reporting contract violations. // This only works if the new handler obeys the constraints placed on // constrained execution regions. Eagerly preparing non-reliable event handlers // would be a perf hit and wouldn't significantly improve reliability. // UE: Please mention reliable event handlers should also be marked with the // PrePrepareMethodAttribute to avoid CER eager preparation work when ngen'ed. #if !FEATURE_CORECLR System.Runtime.CompilerServices.RuntimeHelpers.PrepareContractedDelegate(value); #endif lock (lockObject) { contractFailedEvent += value; } } #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #endif remove { lock (lockObject) { contractFailedEvent -= value; } } } /// /// Rewriter will call this method on a contract failure to allow listeners to be notified. /// The method should not perform any failure (assert/throw) itself. /// This method has 3 functions: /// 1. Call any contract hooks (such as listeners to Contract failed events) /// 2. Determine if the listeneres deem the failure as handled (then resultFailureMessage should be set to null) /// 3. Produce a localized resultFailureMessage used in advertising the failure subsequently. /// /// Should really be out (or the return value), but partial methods are not flexible enough. /// On exit: null if the event was handled and should not trigger a failure. /// Otherwise, returns the localized failure message [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")] [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] [System.Diagnostics.DebuggerNonUserCode] #if FEATURE_RELIABILITY_CONTRACTS [SecuritySafeCritical] #endif static partial void RaiseContractFailedEventImplementation(ContractFailureKind failureKind, String userMessage, String conditionText, Exception innerException, ref string resultFailureMessage) { if (failureKind < ContractFailureKind.Precondition || failureKind > ContractFailureKind.Assume) throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", failureKind), "failureKind"); Contract.EndContractBlock(); String displayMessage = "contract failed."; // Incomplete, but in case of OOM during resource lookup... ContractFailedEventArgs eventArgs = null; // In case of OOM. string returnValue; #if FEATURE_RELIABILITY_CONTRACTS System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); #endif try { displayMessage = GetDisplayMessage(failureKind, userMessage, conditionText); if (contractFailedEvent != null) { eventArgs = new ContractFailedEventArgs(failureKind, displayMessage, conditionText, innerException); foreach (EventHandlerhandler in contractFailedEvent.GetInvocationList()) { try { handler(null, eventArgs); } catch (Exception e) { eventArgs.thrownDuringHandler = e; eventArgs.SetUnwind(); } } if (eventArgs.Unwind) { if (Environment.IsCLRHosted) TriggerCodeContractEscalationPolicy(failureKind, displayMessage, conditionText, innerException); // unwind if (innerException == null) { innerException = eventArgs.thrownDuringHandler; } throw new ContractException(failureKind, displayMessage, userMessage, conditionText, innerException); } } } finally { if (eventArgs != null && eventArgs.Handled) { returnValue = null; // handled } else { returnValue = displayMessage; } } resultFailureMessage = returnValue; } /// /// Rewriter calls this method to get the default failure behavior. /// [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "conditionText")] [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "userMessage")] [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "kind")] [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "innerException")] [System.Diagnostics.DebuggerNonUserCode] #if FEATURE_UNTRUSTED_CALLERS [SecuritySafeCritical] #endif static partial void TriggerFailureImplementation(ContractFailureKind kind, String displayMessage, String userMessage, String conditionText, Exception innerException) { if (Environment.IsCLRHosted) { TriggerCodeContractEscalationPolicy(kind, displayMessage, conditionText, innerException); } #if !FEATURE_PAL if (!Environment.UserInteractive) { Environment.FailFast(displayMessage); } #endif System.Diagnostics.Assert.Check(false, conditionText, displayMessage); } #if FEATURE_RELIABILITY_CONTRACTS [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] #endif private static String GetDisplayMessage(ContractFailureKind failureKind, String userMessage, String conditionText) { String resourceName = null; switch (failureKind) { case ContractFailureKind.Assert: resourceName = "AssertionFailed"; break; case ContractFailureKind.Assume: resourceName = "AssumptionFailed"; break; case ContractFailureKind.Precondition: resourceName = "PreconditionFailed"; break; case ContractFailureKind.Postcondition: resourceName = "PostconditionFailed"; break; case ContractFailureKind.Invariant: resourceName = "InvariantFailed"; break; case ContractFailureKind.PostconditionOnException: resourceName = "PostconditionOnExceptionFailed"; break; default: Contract.Assume(false, "Unreachable code"); resourceName = "AssumptionFailed"; break; } // Well-formatted English messages will take one of four forms. A sentence ending in // either a period or a colon, the condition string, then the message tacked // on to the end with two spaces in front. if (!String.IsNullOrEmpty(conditionText)) resourceName += "_Cnd"; String failureMessage = Environment.GetRuntimeResourceString(resourceName); // Now format based on presence of condition/userProvidedMessage if (!String.IsNullOrEmpty(conditionText)) { if (!String.IsNullOrEmpty(userMessage)) { // both != null return String.Format(System.Globalization.CultureInfo.CurrentUICulture, failureMessage, conditionText) + " " + userMessage; } else { // condition != null, userProvidedMessage == null return String.Format(System.Globalization.CultureInfo.CurrentUICulture, failureMessage, conditionText); } } else { if (!String.IsNullOrEmpty(userMessage)) { // condition null, userProvidedMessage != null return failureMessage + " " + userMessage; } else { // both null return failureMessage; } } } // Will trigger escalation policy, if hosted. Otherwise, exits the process. // We must call through this method before calling the method on the Environment class // because our security team does not yet support SecuritySafeCritical on P/Invoke methods. // Note this can be called in the context of throwing another exception (EnsuresOnThrow). [SecuritySafeCritical] [DebuggerNonUserCode] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private static void TriggerCodeContractEscalationPolicy(ContractFailureKind failureKind, String message, String conditionText, Exception innerException) { String exceptionAsString = null; if (innerException != null) exceptionAsString = innerException.ToString(); Environment.TriggerCodeContractFailure(failureKind, message, conditionText, exceptionAsString); } } } // namespace System.Diagnostics.Contracts.Internal // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: Contract ** **maf,mbarnett,[....] ** ** Implementation details of CLR Contracts. ** ===========================================================*/ #define DEBUG // The behavior of this contract library should be consistent regardless of build type. #if SILVERLIGHT #define FEATURE_UNTRUSTED_CALLERS #elif REDHAWK_RUNTIME #elif BARTOK_RUNTIME #else // CLR #define FEATURE_UNTRUSTED_CALLERS #define FEATURE_RELIABILITY_CONTRACTS #define FEATURE_SERIALIZATION #endif using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; #if FEATURE_RELIABILITY_CONTRACTS using System.Runtime.ConstrainedExecution; #endif #if FEATURE_UNTRUSTED_CALLERS using System.Security; using System.Security.Permissions; #endif namespace System.Diagnostics.Contracts { public static partial class Contract { #region Private Methods private static bool _assertingMustUseRewriter; ////// This method is used internally to trigger a failure indicating to the "programmer" that he is using the interface incorrectly. /// It is NEVER used to indicate failure of actual contracts at runtime. /// static partial void AssertMustUseRewriter(ContractFailureKind kind, String contractKind) { if (_assertingMustUseRewriter) System.Diagnostics.Assert.Fail("Asserting that we must use the rewriter went reentrant.", "Didn't rewrite this mscorlib?"); _assertingMustUseRewriter = true; // @ Internal.ContractHelper.TriggerFailure(kind, "Must use the rewriter when using Contract." + contractKind, null, null, null); _assertingMustUseRewriter = false; } #endregion Private Methods #region Failure Behavior ////// Without contract rewriting, failing Assert/Assumes end up calling this method. /// Code going through the contract rewriter never calls this method. Instead, the rewriter produced failures call /// Internal.ContractHelper.RaiseContractFailedEvent, followed by Internal.ContractHelper.TriggerFailure. /// [SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Security.SecuritySafeCriticalAttribute")] #if FEATURE_UNTRUSTED_CALLERS [SecuritySafeCritical] #endif [System.Diagnostics.DebuggerNonUserCode] #if FEATURE_RELIABILITY_CONTRACTS [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] #endif static partial void ReportFailure(ContractFailureKind failureKind, String userMessage, String conditionText, Exception innerException) { if (failureKind < ContractFailureKind.Precondition || failureKind > ContractFailureKind.Assume) throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", failureKind), "failureKind"); Contract.EndContractBlock(); // displayMessage == null means: yes we handled it. Otherwise it is the localized failure message var displayMessage = Internal.ContractHelper.RaiseContractFailedEvent(failureKind, userMessage, conditionText, innerException); if (displayMessage == null) return; Internal.ContractHelper.TriggerFailure(failureKind, displayMessage, userMessage, conditionText, innerException); } ////// Allows a managed application environment such as an interactive interpreter (IronPython) or a /// web browser host (Jolt hosting Silverlight in IE) to be notified of contract failures and /// potentially "handle" them, either by throwing a particular exception type, etc. If any of the /// event handlers sets the Cancel flag in the ContractFailedEventArgs, then the Contract class will /// not pop up an assert dialog box or trigger escalation policy. Hooking this event requires /// full trust. /// public static event EventHandlerContractFailed { #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #if FEATURE_LINK_DEMAND [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] #endif #endif add { Internal.ContractHelper.InternalContractFailed += value; } #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #if FEATURE_LINK_DEMAND [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] #endif #endif remove { Internal.ContractHelper.InternalContractFailed -= value; } } #endregion FailureBehavior } public sealed class ContractFailedEventArgs : EventArgs { private ContractFailureKind _failureKind; private String _message; private String _condition; private Exception _originalException; private bool _handled; private bool _unwind; internal Exception thrownDuringHandler; #if FEATURE_RELIABILITY_CONTRACTS [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] #endif public ContractFailedEventArgs(ContractFailureKind failureKind, String message, String condition, Exception originalException) { Contract.Requires(originalException == null || failureKind == ContractFailureKind.PostconditionOnException); _failureKind = failureKind; _message = message; _condition = condition; _originalException = originalException; } public String Message { get { return _message; } } public String Condition { get { return _condition; } } public ContractFailureKind FailureKind { get { return _failureKind; } } public Exception OriginalException { get { return _originalException; } } // Whether the event handler "handles" this contract failure, or to fail via escalation policy. public bool Handled { get { return _handled; } } #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #if FEATURE_LINK_DEMAND [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] #endif #endif public void SetHandled() { _handled = true; } public bool Unwind { get { return _unwind; } } #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #if FEATURE_LINK_DEMAND [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] #endif #endif public void SetUnwind() { _unwind = true; } } #if FEATURE_SERIALIZATION [Serializable] #else [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors")] #endif [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")] internal sealed class ContractException : Exception { readonly ContractFailureKind _Kind; readonly string _UserMessage; readonly string _Condition; [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public ContractFailureKind Kind { get { return _Kind; } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string Failure { get { return this.Message; } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string UserMessage { get { return _UserMessage; } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string Condition { get { return _Condition; } } public ContractException() { } #if false public ContractException(string msg) : base(msg) { _Kind = ContractFailureKind.Precondition; } public ContractException(string msg, Exception inner) : base(msg, inner) { } #endif public ContractException(ContractFailureKind kind, string failure, string userMessage, string condition, Exception innerException) : base(failure, innerException) { this._Kind = kind; this._UserMessage = userMessage; this._Condition = condition; } #if FEATURE_SERIALIZATION private ContractException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { _Kind = (ContractFailureKind)info.GetInt32("Kind"); _UserMessage = info.GetString("UserMessage"); _Condition = info.GetString("Condition"); } #endif // FEATURE_SERIALIZATION [System.Runtime.InteropServices.ComVisible(false)] // Hack: This is not necessary, but the BCL's TrimSrc tool // for createBclSmall needs ANY attribute to correctly parse this file. #ifdefs are treated // as whitespace - they're occasionally preserved. #if FEATURE_UNTRUSTED_CALLERS && FEATURE_SERIALIZATION [SecurityCritical] #if FEATURE_LINK_DEMAND && FEATURE_SERIALIZATION [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] #endif // FEATURE_LINK_DEMAND #endif // FEATURE_UNTRUSTED_CALLERS public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { base.GetObjectData(info, context); info.AddValue("Kind", _Kind); info.AddValue("UserMessage", _UserMessage); info.AddValue("Condition", _Condition); } } } namespace System.Diagnostics.Contracts.Internal { public static partial class ContractHelper { #region Private fields private static EventHandler contractFailedEvent; private static readonly Object lockObject = new Object(); #endregion /// /// Allows a managed application environment such as an interactive interpreter (IronPython) or a /// web browser host (Jolt hosting Silverlight in IE) to be notified of contract failures and /// potentially "handle" them, either by throwing a particular exception type, etc. If any of the /// event handlers sets the Cancel flag in the ContractFailedEventArgs, then the Contract class will /// not pop up an assert dialog box or trigger escalation policy. Hooking this event requires /// full trust. /// internal static event EventHandlerInternalContractFailed { #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #endif add { // Eagerly prepare each event handler _marked with a reliability contract_, to // attempt to reduce out of memory exceptions while reporting contract violations. // This only works if the new handler obeys the constraints placed on // constrained execution regions. Eagerly preparing non-reliable event handlers // would be a perf hit and wouldn't significantly improve reliability. // UE: Please mention reliable event handlers should also be marked with the // PrePrepareMethodAttribute to avoid CER eager preparation work when ngen'ed. #if !FEATURE_CORECLR System.Runtime.CompilerServices.RuntimeHelpers.PrepareContractedDelegate(value); #endif lock (lockObject) { contractFailedEvent += value; } } #if FEATURE_UNTRUSTED_CALLERS [SecurityCritical] #endif remove { lock (lockObject) { contractFailedEvent -= value; } } } /// /// Rewriter will call this method on a contract failure to allow listeners to be notified. /// The method should not perform any failure (assert/throw) itself. /// This method has 3 functions: /// 1. Call any contract hooks (such as listeners to Contract failed events) /// 2. Determine if the listeneres deem the failure as handled (then resultFailureMessage should be set to null) /// 3. Produce a localized resultFailureMessage used in advertising the failure subsequently. /// /// Should really be out (or the return value), but partial methods are not flexible enough. /// On exit: null if the event was handled and should not trigger a failure. /// Otherwise, returns the localized failure message [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")] [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] [System.Diagnostics.DebuggerNonUserCode] #if FEATURE_RELIABILITY_CONTRACTS [SecuritySafeCritical] #endif static partial void RaiseContractFailedEventImplementation(ContractFailureKind failureKind, String userMessage, String conditionText, Exception innerException, ref string resultFailureMessage) { if (failureKind < ContractFailureKind.Precondition || failureKind > ContractFailureKind.Assume) throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", failureKind), "failureKind"); Contract.EndContractBlock(); String displayMessage = "contract failed."; // Incomplete, but in case of OOM during resource lookup... ContractFailedEventArgs eventArgs = null; // In case of OOM. string returnValue; #if FEATURE_RELIABILITY_CONTRACTS System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); #endif try { displayMessage = GetDisplayMessage(failureKind, userMessage, conditionText); if (contractFailedEvent != null) { eventArgs = new ContractFailedEventArgs(failureKind, displayMessage, conditionText, innerException); foreach (EventHandlerhandler in contractFailedEvent.GetInvocationList()) { try { handler(null, eventArgs); } catch (Exception e) { eventArgs.thrownDuringHandler = e; eventArgs.SetUnwind(); } } if (eventArgs.Unwind) { if (Environment.IsCLRHosted) TriggerCodeContractEscalationPolicy(failureKind, displayMessage, conditionText, innerException); // unwind if (innerException == null) { innerException = eventArgs.thrownDuringHandler; } throw new ContractException(failureKind, displayMessage, userMessage, conditionText, innerException); } } } finally { if (eventArgs != null && eventArgs.Handled) { returnValue = null; // handled } else { returnValue = displayMessage; } } resultFailureMessage = returnValue; } /// /// Rewriter calls this method to get the default failure behavior. /// [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "conditionText")] [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "userMessage")] [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "kind")] [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "innerException")] [System.Diagnostics.DebuggerNonUserCode] #if FEATURE_UNTRUSTED_CALLERS [SecuritySafeCritical] #endif static partial void TriggerFailureImplementation(ContractFailureKind kind, String displayMessage, String userMessage, String conditionText, Exception innerException) { if (Environment.IsCLRHosted) { TriggerCodeContractEscalationPolicy(kind, displayMessage, conditionText, innerException); } #if !FEATURE_PAL if (!Environment.UserInteractive) { Environment.FailFast(displayMessage); } #endif System.Diagnostics.Assert.Check(false, conditionText, displayMessage); } #if FEATURE_RELIABILITY_CONTRACTS [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] #endif private static String GetDisplayMessage(ContractFailureKind failureKind, String userMessage, String conditionText) { String resourceName = null; switch (failureKind) { case ContractFailureKind.Assert: resourceName = "AssertionFailed"; break; case ContractFailureKind.Assume: resourceName = "AssumptionFailed"; break; case ContractFailureKind.Precondition: resourceName = "PreconditionFailed"; break; case ContractFailureKind.Postcondition: resourceName = "PostconditionFailed"; break; case ContractFailureKind.Invariant: resourceName = "InvariantFailed"; break; case ContractFailureKind.PostconditionOnException: resourceName = "PostconditionOnExceptionFailed"; break; default: Contract.Assume(false, "Unreachable code"); resourceName = "AssumptionFailed"; break; } // Well-formatted English messages will take one of four forms. A sentence ending in // either a period or a colon, the condition string, then the message tacked // on to the end with two spaces in front. if (!String.IsNullOrEmpty(conditionText)) resourceName += "_Cnd"; String failureMessage = Environment.GetRuntimeResourceString(resourceName); // Now format based on presence of condition/userProvidedMessage if (!String.IsNullOrEmpty(conditionText)) { if (!String.IsNullOrEmpty(userMessage)) { // both != null return String.Format(System.Globalization.CultureInfo.CurrentUICulture, failureMessage, conditionText) + " " + userMessage; } else { // condition != null, userProvidedMessage == null return String.Format(System.Globalization.CultureInfo.CurrentUICulture, failureMessage, conditionText); } } else { if (!String.IsNullOrEmpty(userMessage)) { // condition null, userProvidedMessage != null return failureMessage + " " + userMessage; } else { // both null return failureMessage; } } } // Will trigger escalation policy, if hosted. Otherwise, exits the process. // We must call through this method before calling the method on the Environment class // because our security team does not yet support SecuritySafeCritical on P/Invoke methods. // Note this can be called in the context of throwing another exception (EnsuresOnThrow). [SecuritySafeCritical] [DebuggerNonUserCode] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private static void TriggerCodeContractEscalationPolicy(ContractFailureKind failureKind, String message, String conditionText, Exception innerException) { String exceptionAsString = null; if (innerException != null) exceptionAsString = innerException.ToString(); Environment.TriggerCodeContractFailure(failureKind, message, conditionText, exceptionAsString); } } } // namespace System.Diagnostics.Contracts.Internal // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- OperationCanceledException.cs
- altserialization.cs
- StandardToolWindows.cs
- shaper.cs
- TranslateTransform3D.cs
- SuspendDesigner.cs
- XslException.cs
- TypeDependencyAttribute.cs
- Match.cs
- PassportAuthenticationEventArgs.cs
- WebPartConnectionsEventArgs.cs
- _SslSessionsCache.cs
- PasswordBoxAutomationPeer.cs
- UnicodeEncoding.cs
- GenericUI.cs
- LinkConverter.cs
- TransactionWaitAsyncResult.cs
- ImmutableCommunicationTimeouts.cs
- InkCanvasAutomationPeer.cs
- rsa.cs
- Size.cs
- RTLAwareMessageBox.cs
- StrokeDescriptor.cs
- GetLedgerEntryForRecipientRequest.cs
- DispatcherProcessingDisabled.cs
- WSHttpSecurityElement.cs
- CustomError.cs
- webclient.cs
- CustomValidator.cs
- SystemWebExtensionsSectionGroup.cs
- WebSysDisplayNameAttribute.cs
- PropertyTabAttribute.cs
- Style.cs
- UserPreferenceChangedEventArgs.cs
- PingOptions.cs
- _LoggingObject.cs
- HttpFormatExtensions.cs
- WebPartConnectionsCloseVerb.cs
- ImageMetadata.cs
- SkewTransform.cs
- ProgressBarHighlightConverter.cs
- ContextStaticAttribute.cs
- hresults.cs
- XsltFunctions.cs
- DataControlFieldCell.cs
- WindowsRichEdit.cs
- RoleManagerSection.cs
- OleDbConnectionPoolGroupProviderInfo.cs
- DbConnectionPoolOptions.cs
- ImageIndexConverter.cs
- CatalogZone.cs
- ReadOnlyTernaryTree.cs
- HttpSessionStateBase.cs
- MetadataArtifactLoaderComposite.cs
- COM2PropertyDescriptor.cs
- TransportationConfigurationTypeInstallComponent.cs
- WebBrowserProgressChangedEventHandler.cs
- HostAdapter.cs
- LoginName.cs
- ValuePatternIdentifiers.cs
- DropShadowBitmapEffect.cs
- StrokeIntersection.cs
- QuadraticBezierSegment.cs
- XslVisitor.cs
- InstanceNormalEvent.cs
- SpeechDetectedEventArgs.cs
- CFGGrammar.cs
- MethodImplAttribute.cs
- NullableLongAverageAggregationOperator.cs
- FormViewUpdatedEventArgs.cs
- COAUTHIDENTITY.cs
- TreeNodeBinding.cs
- BaseUriHelper.cs
- DefaultValueAttribute.cs
- XmlDataContract.cs
- WorkflowInstance.cs
- TableLayoutSettingsTypeConverter.cs
- ClipboardProcessor.cs
- AnnotationHelper.cs
- uribuilder.cs
- WebPartCatalogCloseVerb.cs
- HierarchicalDataSourceControl.cs
- UrlUtility.cs
- BindingExpressionUncommonField.cs
- ProxyAttribute.cs
- DictionaryContent.cs
- XamlBrushSerializer.cs
- CryptoStream.cs
- UnauthorizedWebPart.cs
- AutomationIdentifierGuids.cs
- Compiler.cs
- Validator.cs
- FormClosingEvent.cs
- WindowsListViewGroupSubsetLink.cs
- Graph.cs
- CollectionViewGroup.cs
- GridItemCollection.cs
- ECDsaCng.cs
- SecurityResources.cs
- DbConnectionStringCommon.cs