// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // // Microsoft // // ==--== /*============================================================================= ** ** Class: Exception ** ** ** Purpose: The base class for all exceptional conditions. ** ** =============================================================================*/ namespace System { using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Diagnostics; using System.Security.Permissions; using System.Security; using System.IO; using System.Text; using System.Reflection; using System.Collections; using System.Globalization; using System.Diagnostics.Contracts; [ClassInterface(ClassInterfaceType.None)] [ComDefaultInterface(typeof(_Exception))] [Serializable] [ComVisible(true)] public class Exception : ISerializable, _Exception { private void Init() { _message = null; _stackTrace = null; _dynamicMethods = null; HResult = __HResults.COR_E_EXCEPTION; _xcode = _COMPlusExceptionCode; _xptrs = (IntPtr) 0; // Initialize the WatsonBuckets to be null _watsonBuckets = null; // Initialize the watson bucketing IP _ipForWatsonBuckets = UIntPtr.Zero; #if FEATURE_SERIALIZATION _safeSerializationManager = new SafeSerializationManager(); #endif // FEATURE_SERIALIZATION } public Exception() { Init(); } public Exception(String message) { Init(); _message = message; } // Creates a new Exception. All derived classes should // provide this constructor. // Note: the stack trace is not started until the exception // is thrown // public Exception (String message, Exception innerException) { Init(); _message = message; _innerException = innerException; } [System.Security.SecuritySafeCritical] // auto-generated protected Exception(SerializationInfo info, StreamingContext context) { if (info==null) throw new ArgumentNullException("info"); Contract.EndContractBlock(); _className = info.GetString("ClassName"); _message = info.GetString("Message"); _data = (IDictionary)(info.GetValueNoThrow("Data",typeof(IDictionary))); _innerException = (Exception)(info.GetValue("InnerException",typeof(Exception))); _helpURL = info.GetString("HelpURL"); _stackTraceString = info.GetString("StackTraceString"); _remoteStackTraceString = info.GetString("RemoteStackTraceString"); _remoteStackIndex = info.GetInt32("RemoteStackIndex"); _exceptionMethodString = (String)(info.GetValue("ExceptionMethod",typeof(String))); HResult = info.GetInt32("HResult"); _source = info.GetString("Source"); // Get the WatsonBuckets that were serialized - this is particularly // done to support exceptions going across AD transitions. // // We use the no throw version since we could be deserializing a pre-V4 // exception object that may not have this entry. In such a case, we would // get null. _watsonBuckets = (Object)info.GetValueNoThrow("WatsonBuckets", typeof(byte[])); #if FEATURE_SERIALIZATION _safeSerializationManager = info.GetValueNoThrow("SafeSerializationManager", typeof(SafeSerializationManager)) as SafeSerializationManager; #endif // FEATURE_SERIALIZATION if (_className == null || HResult==0) throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState")); // If we are constructing a new exception after a cross-appdomain call... if (context.State == StreamingContextStates.CrossAppDomain) { // ...this new exception may get thrown. It is logically a re-throw, but // physically a brand-new exception. Since the stack trace is cleared // on a new exception, the "_remoteStackTraceString" is provided to // effectively import a stack trace from a "remote" exception. So, // move the _stackTraceString into the _remoteStackTraceString. Note // that if there is an existing _remoteStackTraceString, it will be // preserved at the head of the new string, so everything works as // expected. // Even if this exception is NOT thrown, things will still work as expected // because the StackTrace property returns the concatenation of the // _remoteStackTraceString and the _stackTraceString. _remoteStackTraceString = _remoteStackTraceString + _stackTraceString; _stackTraceString = null; } } public virtual String Message { get { if (_message == null) { if (_className==null) { _className = GetClassName(); } return Environment.GetResourceString("Exception_WasThrown", _className); } else { return _message; } } } public virtual IDictionary Data { [System.Security.SecuritySafeCritical] // auto-generated get { if (_data == null) if (IsImmutableAgileException(this)) _data = new EmptyReadOnlyDictionaryInternal(); else _data = new ListDictionaryInternal(); return _data; } } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool IsImmutableAgileException(Exception e); #if FEATURE_COMINTEROP // // Exception requires anything to be added into Data dictionary is serializable // This wrapper is made serializable to satisfy this requirement but does NOT serialize // the object and simply ignores it during serialization, because we only need // the exception instance in the app to hold the error object alive. // Once the exception is serialized to debugger, debugger only needs the error reference string // [Serializable] internal class __RestrictedErrorObject { // Hold the error object instance but don't serialize/deserialize it [NonSerialized] private object _realErrorObject; internal __RestrictedErrorObject(object errorObject) { _realErrorObject = errorObject; } public object RealErrorObject { get { return _realErrorObject; } } } [FriendAccessAllowed] internal void AddExceptionDataForRestrictedErrorInfo( string restrictedError, string restrictedErrorReference, string restrictedCapabilitySid, object restrictedErrorObject, bool hasrestrictedLanguageErrorObject = false) { IDictionary dict = Data; if (dict != null) { dict.Add("RestrictedDescription", restrictedError); dict.Add("RestrictedErrorReference", restrictedErrorReference); dict.Add("RestrictedCapabilitySid", restrictedCapabilitySid); // Keep the error object alive so that user could retrieve error information // using Data["RestrictedErrorReference"] dict.Add("__RestrictedErrorObject", (restrictedErrorObject == null ? null : new __RestrictedErrorObject(restrictedErrorObject))); dict.Add("__HasRestrictedLanguageErrorObject", hasrestrictedLanguageErrorObject); } } internal bool TryGetRestrictedLanguageErrorObject(out object restrictedErrorObject) { restrictedErrorObject = null; if (Data != null && Data.Contains("__HasRestrictedLanguageErrorObject")) { if (Data.Contains("__RestrictedErrorObject")) { __RestrictedErrorObject restrictedObject = Data["__RestrictedErrorObject"] as __RestrictedErrorObject; if (restrictedObject != null) restrictedErrorObject = restrictedObject.RealErrorObject; } return (bool)Data["__HasRestrictedLanguageErrorObject"]; } return false; } #endif // FEATURE_COMINTEROP private string GetClassName() { // Will include namespace but not full instantiation and assembly name. if (_className == null) _className = GetType().ToString(); return _className; } // Retrieves the lowest exception (inner most) for the given Exception. // This will traverse exceptions using the innerException property. // public virtual Exception GetBaseException() { Exception inner = InnerException; Exception back = this; while (inner != null) { back = inner; inner = inner.InnerException; } return back; } // Returns the inner exception contained in this exception // public Exception InnerException { get { return _innerException; } } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern private IRuntimeMethodInfo GetMethodFromStackTrace(Object stackTrace); [System.Security.SecuritySafeCritical] // auto-generated private MethodBase GetExceptionMethodFromStackTrace() { IRuntimeMethodInfo method = GetMethodFromStackTrace(_stackTrace); // Under certain race conditions when exceptions are re-used, this can be null if (method == null) return null; return RuntimeType.GetMethodBase(method); } public MethodBase TargetSite { [System.Security.SecuritySafeCritical] // auto-generated get { return GetTargetSiteInternal(); } } // this function is provided as a private helper to avoid the security demand [System.Security.SecurityCritical] // auto-generated private MethodBase GetTargetSiteInternal() { if (_exceptionMethod!=null) { return _exceptionMethod; } if (_stackTrace==null) { return null; } if (_exceptionMethodString!=null) { _exceptionMethod = GetExceptionMethodFromString(); } else { _exceptionMethod = GetExceptionMethodFromStackTrace(); } return _exceptionMethod; } // Returns the stack trace as a string. If no stack trace is // available, null is returned. public virtual String StackTrace { #if FEATURE_CORECLR [System.Security.SecuritySafeCritical] #endif get { // By default attempt to include file and line number info return GetStackTrace(true); } } // Computes and returns the stack trace as a string // Attempts to get source file and line number information if needFileInfo // is true. Note that this requires FileIOPermission(PathDiscovery), and so // will usually fail in CoreCLR. To avoid the demand and resulting // SecurityException we can explicitly not even try to get fileinfo. #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #endif private string GetStackTrace(bool needFileInfo) { string stackTraceString = _stackTraceString; string remoteStackTraceString = _remoteStackTraceString; #if !FEATURE_CORECLR if (!needFileInfo) { // Filter out file names/paths and line numbers from _stackTraceString and _remoteStackTraceString. // This is used only when generating stack trace for Watson where the strings must be PII-free. stackTraceString = StripFileInfo(stackTraceString, false); remoteStackTraceString = StripFileInfo(remoteStackTraceString, true); } #endif // !FEATURE_CORECLR // if no stack trace, try to get one if (stackTraceString != null) { return remoteStackTraceString + stackTraceString; } if (_stackTrace == null) { return remoteStackTraceString; } // Obtain the stack trace string. Note that since Environment.GetStackTrace // will add the path to the source file if the PDB is present and a demand // for FileIOPermission(PathDiscovery) succeeds, we need to make sure we // don't store the stack trace string in the _stackTraceString member variable. String tempStackTraceString = Environment.GetStackTrace(this, needFileInfo); return remoteStackTraceString + tempStackTraceString; } [FriendAccessAllowed] internal void SetErrorCode(int hr) { HResult = hr; } // Sets the help link for this exception. // This should be in a URL/URN form, such as: // "file:///C:/Applications/Bazzal/help.html#ErrorNum42" // Changed to be a read-write String and not return an exception public virtual String HelpLink { get { return _helpURL; } set { _helpURL = value; } } public virtual String Source { #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #endif get { if (_source == null) { StackTrace st = new StackTrace(this,true); if (st.FrameCount>0) { StackFrame sf = st.GetFrame(0); MethodBase method = sf.GetMethod(); Module module = method.Module; RuntimeModule rtModule = module as RuntimeModule; if (rtModule == null) { System.Reflection.Emit.ModuleBuilder moduleBuilder = module as System.Reflection.Emit.ModuleBuilder; if (moduleBuilder != null) rtModule = moduleBuilder.InternalModule; else throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeReflectionObject")); } _source = rtModule.GetRuntimeAssembly().GetSimpleName(); } } return _source; } #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #endif set { _source = value; } } #if FEATURE_CORECLR [System.Security.SecuritySafeCritical] #endif public override String ToString() { return ToString(true, true); } #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #endif private String ToString(bool needFileLineInfo, bool needMessage) { String message = (needMessage ? Message : null); String s; if (message == null || message.Length <= 0) { s = GetClassName(); } else { s = GetClassName() + ": " + message; } if (_innerException!=null) { s = s + " ---> " + _innerException.ToString(needFileLineInfo, needMessage) + Environment.NewLine + " " + Environment.GetResourceString("Exception_EndOfInnerExceptionStack"); } string stackTrace = GetStackTrace(needFileLineInfo); if (stackTrace != null) { s += Environment.NewLine + stackTrace; } return s; } [System.Security.SecurityCritical] // auto-generated private String GetExceptionMethodString() { MethodBase methBase = GetTargetSiteInternal(); if (methBase==null) { return null; } if (methBase is System.Reflection.Emit.DynamicMethod.RTDynamicMethod) { // DynamicMethods cannot be serialized return null; } // Note that the newline separator is only a separator, chosen such that // it won't (generally) occur in a method name. This string is used // only for serialization of the Exception Method. char separator = '\n'; StringBuilder result = new StringBuilder(); if (methBase is ConstructorInfo) { RuntimeConstructorInfo rci = (RuntimeConstructorInfo)methBase; Type t = rci.ReflectedType; result.Append((int)MemberTypes.Constructor); result.Append(separator); result.Append(rci.Name); if (t!=null) { result.Append(separator); result.Append(t.Assembly.FullName); result.Append(separator); result.Append(t.FullName); } result.Append(separator); result.Append(rci.ToString()); } else { Contract.Assert(methBase is MethodInfo, "[Exception.GetExceptionMethodString]methBase is MethodInfo"); RuntimeMethodInfo rmi = (RuntimeMethodInfo)methBase; Type t = rmi.DeclaringType; result.Append((int)MemberTypes.Method); result.Append(separator); result.Append(rmi.Name); result.Append(separator); result.Append(rmi.Module.Assembly.FullName); result.Append(separator); if (t != null) { result.Append(t.FullName); result.Append(separator); } result.Append(rmi.ToString()); } return result.ToString(); } [System.Security.SecurityCritical] // auto-generated private MethodBase GetExceptionMethodFromString() { Contract.Assert(_exceptionMethodString != null, "Method string cannot be NULL!"); String[] args = _exceptionMethodString.Split(new char[]{'\0', '\n'}); if (args.Length!=5) { throw new SerializationException(); } SerializationInfo si = new SerializationInfo(typeof(MemberInfoSerializationHolder), new FormatterConverter()); si.AddValue("MemberType", (int)Int32.Parse(args[0], CultureInfo.InvariantCulture), typeof(Int32)); si.AddValue("Name", args[1], typeof(String)); si.AddValue("AssemblyName", args[2], typeof(String)); si.AddValue("ClassName", args[3]); si.AddValue("Signature", args[4]); MethodBase result; StreamingContext sc = new StreamingContext(StreamingContextStates.All); try { result = (MethodBase)new MemberInfoSerializationHolder(si, sc).GetRealObject(sc); } catch (SerializationException) { result = null; } return result; } #if FEATURE_SERIALIZATION protected event EventHandler SerializeObjectState { add { _safeSerializationManager.SerializeObjectState += value; } remove { _safeSerializationManager.SerializeObjectState -= value; } } #endif // FEATURE_SERIALIZATION [System.Security.SecurityCritical] // auto-generated_required public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) { throw new ArgumentNullException("info"); } Contract.EndContractBlock(); String tempStackTraceString = _stackTraceString; if (_stackTrace!=null) { if (tempStackTraceString==null) { tempStackTraceString = Environment.GetStackTrace(this, true); } if (_exceptionMethod==null) { _exceptionMethod = GetExceptionMethodFromStackTrace(); } } if (_source == null) { _source = Source; // Set the Source information correctly before serialization } info.AddValue("ClassName", GetClassName(), typeof(String)); info.AddValue("Message", _message, typeof(String)); info.AddValue("Data", _data, typeof(IDictionary)); info.AddValue("InnerException", _innerException, typeof(Exception)); info.AddValue("HelpURL", _helpURL, typeof(String)); info.AddValue("StackTraceString", tempStackTraceString, typeof(String)); info.AddValue("RemoteStackTraceString", _remoteStackTraceString, typeof(String)); info.AddValue("RemoteStackIndex", _remoteStackIndex, typeof(Int32)); info.AddValue("ExceptionMethod", GetExceptionMethodString(), typeof(String)); info.AddValue("HResult", HResult); info.AddValue("Source", _source, typeof(String)); // Serialize the Watson bucket details as well info.AddValue("WatsonBuckets", _watsonBuckets, typeof(byte[])); #if FEATURE_SERIALIZATION if (_safeSerializationManager != null && _safeSerializationManager.IsActive) { info.AddValue("SafeSerializationManager", _safeSerializationManager, typeof(SafeSerializationManager)); // User classes derived from Exception must have a valid _safeSerializationManager. // Exceptions defined in mscorlib don't use this field might not have it initalized (since they are // often created in the VM with AllocateObject instead if the managed construtor) // If you are adding code to use a SafeSerializationManager from an mscorlib exception, update // this assert to ensure that it fails when that exception's _safeSerializationManager is NULL Contract.Assert(((_safeSerializationManager != null) || (this.GetType().Assembly == typeof(object).Assembly)), "User defined exceptions must have a valid _safeSerializationManager"); // Handle serializing any transparent or partial trust subclass data _safeSerializationManager.CompleteSerialization(this, info, context); } #endif // FEATURE_SERIALIZATION } // This is used by remoting to preserve the server side stack trace // by appending it to the message ... before the exception is rethrown // at the client call site. internal Exception PrepForRemoting() { String tmp = null; if (_remoteStackIndex == 0) { tmp = Environment.NewLine+ "Server stack trace: " + Environment.NewLine + StackTrace + Environment.NewLine + Environment.NewLine + "Exception rethrown at ["+_remoteStackIndex+"]: " + Environment.NewLine; } else { tmp = StackTrace + Environment.NewLine + Environment.NewLine + "Exception rethrown at ["+_remoteStackIndex+"]: " + Environment.NewLine; } _remoteStackTraceString = tmp; _remoteStackIndex++; return this; } // This method will clear the _stackTrace of the exception object upon deserialization // to ensure that references from another AD/Process dont get accidently used. [OnDeserialized] private void OnDeserialized(StreamingContext context) { _stackTrace = null; // We wont serialize or deserialize the IP for Watson bucketing since // we dont know where the deserialized object will be used in. // Using it across process or an AppDomain could be invalid and result // in AV in the runtime. // // Hence, we set it to zero when deserialization takes place. _ipForWatsonBuckets = UIntPtr.Zero; #if FEATURE_SERIALIZATION if (_safeSerializationManager == null) { _safeSerializationManager = new SafeSerializationManager(); } else { _safeSerializationManager.CompleteDeserialization(this); } #endif // FEATURE_SERIALIZATION } // This is used by the runtime when re-throwing a managed exception. It will // copy the stack trace to _remoteStackTraceString. #if FEATURE_CORECLR [System.Security.SecuritySafeCritical] #endif internal void InternalPreserveStackTrace() { string tmpStackTraceString; #if FEATURE_APPX if (AppDomain.IsAppXModel()) { // Call our internal GetStackTrace in AppX so we can parse the result should // we need to strip file/line info from it to make it PII-free. Calling the // public and overridable StackTrace getter here was probably not intended. tmpStackTraceString = GetStackTrace(true); // Make sure that the _source field is initialized if Source is not overriden. // We want it to contain the original faulting point. string source = Source; } else #else // FEATURE_APPX #if FEATURE_CORESYSTEM // Preinitialize _source on CoreSystem as well. The legacy behavior is not ideal and // we keep it for back compat but we can afford to make the change on the Phone. string source = Source; #endif // FEATURE_CORESYSTEM #endif // FEATURE_APPX { // Call the StackTrace getter in classic for compat. tmpStackTraceString = StackTrace; } if (tmpStackTraceString != null && tmpStackTraceString.Length > 0) { _remoteStackTraceString = tmpStackTraceString + Environment.NewLine; } _stackTrace = null; _stackTraceString = null; } #if FEATURE_EXCEPTIONDISPATCHINFO // This is the object against which a lock will be taken // when attempt to restore the EDI. Since its static, its possible // that unrelated exception object restorations could get blocked // for a small duration but that sounds reasonable considering // such scenarios are going to be extremely rare, where timing // matches precisely. [OptionalField] private static object s_EDILock = new object(); internal UIntPtr IPForWatsonBuckets { get { return _ipForWatsonBuckets; } } internal object WatsonBuckets { get { return _watsonBuckets; } } internal string RemoteStackTrace { get { return _remoteStackTraceString; } } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void PrepareForForeignExceptionRaise(); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void GetStackTracesDeepCopy(Exception exception, out object currentStackTrace, out object dynamicMethodArray); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void SaveStackTracesFromDeepCopy(Exception exception, object currentStackTrace, object dynamicMethodArray); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern object CopyStackTrace(object currentStackTrace); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern object CopyDynamicMethods(object currentDynamicMethods); #if !FEATURE_CORECLR [System.Security.SecuritySafeCritical] [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern string StripFileInfo(string stackTrace, bool isRemoteStackTrace); #endif // !FEATURE_CORECLR [SecuritySafeCritical] internal object DeepCopyStackTrace(object currentStackTrace) { if (currentStackTrace != null) { return CopyStackTrace(currentStackTrace); } else { return null; } } [SecuritySafeCritical] internal object DeepCopyDynamicMethods(object currentDynamicMethods) { if (currentDynamicMethods != null) { return CopyDynamicMethods(currentDynamicMethods); } else { return null; } } [SecuritySafeCritical] internal void GetStackTracesDeepCopy(out object currentStackTrace, out object dynamicMethodArray) { GetStackTracesDeepCopy(this, out currentStackTrace, out dynamicMethodArray); } // This is invoked by ExceptionDispatchInfo.Throw to restore the exception stack trace, corresponding to the original throw of the // exception, just before the exception is "rethrown". [SecuritySafeCritical] internal void RestoreExceptionDispatchInfo(System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo) { bool fCanProcessException = !(IsImmutableAgileException(this)); // Restore only for non-preallocated exceptions if (fCanProcessException) { // Take a lock to ensure only one thread can restore the details // at a time against this exception object that could have // multiple ExceptionDispatchInfo instances associated with it. // // We do this inside a finally clause to ensure ThreadAbort cannot // be injected while we have taken the lock. This is to prevent // unrelated exception restorations from getting blocked due to TAE. try{} finally { // When restoring back the fields, we again create a copy and set reference to them // in the exception object. This will ensure that when this exception is thrown and these // fields are modified, then EDI's references remain intact. // // Since deep copying can throw on OOM, try to get the copies // outside the lock. object _stackTraceCopy = (exceptionDispatchInfo.BinaryStackTraceArray == null)?null:DeepCopyStackTrace(exceptionDispatchInfo.BinaryStackTraceArray); object _dynamicMethodsCopy = (exceptionDispatchInfo.DynamicMethodArray == null)?null:DeepCopyDynamicMethods(exceptionDispatchInfo.DynamicMethodArray); // Finally, restore the information. // // Since EDI can be created at various points during exception dispatch (e.g. at various frames on the stack) for the same exception instance, // they can have different data to be restored. Thus, to ensure atomicity of restoration from each EDI, perform the restore under a lock. lock(Exception.s_EDILock) { _watsonBuckets = exceptionDispatchInfo.WatsonBuckets; _ipForWatsonBuckets = exceptionDispatchInfo.IPForWatsonBuckets; _remoteStackTraceString = exceptionDispatchInfo.RemoteStackTrace; SaveStackTracesFromDeepCopy(this, _stackTraceCopy, _dynamicMethodsCopy); } _stackTraceString = null; // Marks the TES state to indicate we have restored foreign exception // dispatch information. Exception.PrepareForForeignExceptionRaise(); } } } #endif // FEATURE_EXCEPTIONDISPATCHINFO private String _className; //Needed for serialization. private MethodBase _exceptionMethod; //Needed for serialization. private String _exceptionMethodString; //Needed for serialization. internal String _message; private IDictionary _data; private Exception _innerException; private String _helpURL; private Object _stackTrace; [OptionalField] // This isnt present in pre-V4 exception objects that would be serialized. private Object _watsonBuckets; private String _stackTraceString; //Needed for serialization. private String _remoteStackTraceString; private int _remoteStackIndex; #pragma warning disable 414 // Field is not used from managed. // _dynamicMethods is an array of System.Resolver objects, used to keep // DynamicMethodDescs alive for the lifetime of the exception. We do this because // the _stackTrace field holds MethodDescs, and a DynamicMethodDesc can be destroyed // unless a System.Resolver object roots it. private Object _dynamicMethods; #pragma warning restore 414 // @MANAGED: HResult is used from within the EE! Rename with care - check VM directory internal int _HResult; // HResult public int HResult { get { return _HResult; } protected set { _HResult = value; } } private String _source; // Mainly used by VB. // WARNING: Don't delete/rename _xptrs and _xcode - used by functions // on Marshal class. Native functions are in COMUtilNative.cpp & AppDomain private IntPtr _xptrs; // Internal EE stuff #pragma warning disable 414 // Field is not used from managed. private int _xcode; // Internal EE stuff #pragma warning restore 414 [OptionalField] private UIntPtr _ipForWatsonBuckets; // Used to persist the IP for Watson Bucketing #if FEATURE_SERIALIZATION [OptionalField(VersionAdded = 4)] private SafeSerializationManager _safeSerializationManager; #endif // FEATURE_SERIALIZATION // See clr\src\vm\excep.h's EXCEPTION_COMPLUS definition: private const int _COMPlusExceptionCode = unchecked((int)0xe0434352); // Win32 exception code for COM+ exceptions // InternalToString is called by the runtime to get the exception text // and create a corresponding CrossAppDomainMarshaledException [System.Security.SecurityCritical] // auto-generated internal virtual String InternalToString() { try { #pragma warning disable 618 SecurityPermission sp= new SecurityPermission(SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy); #pragma warning restore 618 sp.Assert(); } catch { //under normal conditions there should be no exceptions //however if something wrong happens we still can call the usual ToString } // Get the current stack trace string. On CoreCLR we don't bother // to try and include file/line-number information because all AppDomains // are sandboxed, and so this won't succeed in most (or all) cases. Therefore the // Demand and exception overhead is a waste. // We currently have some bugs in watson bucket generation where the SecurityException // here causes us to lose saved bucket parameters. By not even doing the demand // we avoid those problems (although there are deep underlying problems that need to // be fixed there - relying on this to avoid problems is incomplete and brittle). bool fGetFileLineInfo = true; #if FEATURE_CORECLR fGetFileLineInfo = false; #endif return ToString(fGetFileLineInfo, true); } #if !FEATURE_CORECLR // this method is required so Object.GetType is not made virtual by the compiler // _Exception.GetType() public new Type GetType() { return base.GetType(); } #endif internal bool IsTransient { [System.Security.SecuritySafeCritical] // auto-generated get { return nIsTransient(_HResult); } } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern static bool nIsTransient(int hr); // This piece of infrastructure exists to help avoid deadlocks // between parts of mscorlib that might throw an exception while // holding a lock that are also used by mscorlib's ResourceManager // instance. As a special case of code that may throw while holding // a lock, we also need to fix our asynchronous exceptions to use // Win32 resources as well (assuming we ever call a managed // constructor on instances of them). We should grow this set of // exception messages as we discover problems, then move the resources // involved to native code. internal enum ExceptionMessageKind { ThreadAbort = 1, ThreadInterrupted = 2, OutOfMemory = 3 } // See comment on ExceptionMessageKind [System.Security.SecuritySafeCritical] // auto-generated internal static String GetMessageFromNativeResources(ExceptionMessageKind kind) { string retMesg = null; GetMessageFromNativeResources(kind, JitHelpers.GetStringHandleOnStack(ref retMesg)); return retMesg; } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void GetMessageFromNativeResources(ExceptionMessageKind kind, StringHandleOnStack retMesg); } #if FEATURE_CORECLR //-------------------------------------------------------------------------- // Telesto: Telesto doesn't support appdomain marshaling of objects so // managed exceptions that leak across appdomain boundaries are flatted to // its ToString() output and rethrown as an CrossAppDomainMarshaledException. // The Message field is set to the ToString() output of the original exception. //-------------------------------------------------------------------------- [Serializable] internal sealed class CrossAppDomainMarshaledException : SystemException { public CrossAppDomainMarshaledException(String message, int errorCode) : base(message) { SetErrorCode(errorCode); } // Normally, only Telesto's UEF will see these exceptions. // This override prints out the original Exception's ToString() // output and hides the fact that it is wrapped inside another excepton. #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #endif internal override String InternalToString() { return Message; } } #endif }