3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>[....]</OWNER>
9 /*=============================================================================
14 ** Purpose: The base class for all exceptional conditions.
17 =============================================================================*/
21 using System.Runtime.InteropServices;
22 using System.Runtime.CompilerServices;
23 using System.Runtime.Serialization;
24 using System.Runtime.Versioning;
25 using System.Diagnostics;
26 using System.Security.Permissions;
27 using System.Security;
30 using System.Reflection;
31 using System.Collections;
32 using System.Globalization;
33 using System.Diagnostics.Contracts;
35 [ClassInterface(ClassInterfaceType.None)]
36 [ComDefaultInterface(typeof(_Exception))]
40 [StructLayout (LayoutKind.Sequential)]
42 public class Exception : ISerializable
51 _dynamicMethods = null;
52 HResult = __HResults.COR_E_EXCEPTION;
54 _xcode = _COMPlusExceptionCode;
57 // Initialize the WatsonBuckets to be null
58 _watsonBuckets = null;
60 // Initialize the watson bucketing IP
61 _ipForWatsonBuckets = UIntPtr.Zero;
64 #if FEATURE_SERIALIZATION
65 _safeSerializationManager = new SafeSerializationManager();
66 #endif // FEATURE_SERIALIZATION
73 public Exception(String message) {
78 // Creates a new Exception. All derived classes should
79 // provide this constructor.
80 // Note: the stack trace is not started until the exception
83 public Exception (String message, Exception innerException) {
86 _innerException = innerException;
89 [System.Security.SecuritySafeCritical] // auto-generated
90 protected Exception(SerializationInfo info, StreamingContext context)
93 throw new ArgumentNullException("info");
94 Contract.EndContractBlock();
96 _className = info.GetString("ClassName");
97 _message = info.GetString("Message");
98 _data = (IDictionary)(info.GetValueNoThrow("Data",typeof(IDictionary)));
99 _innerException = (Exception)(info.GetValue("InnerException",typeof(Exception)));
100 _helpURL = info.GetString("HelpURL");
101 _stackTraceString = info.GetString("StackTraceString");
102 _remoteStackTraceString = info.GetString("RemoteStackTraceString");
103 _remoteStackIndex = info.GetInt32("RemoteStackIndex");
106 _exceptionMethodString = (String)(info.GetValue("ExceptionMethod",typeof(String)));
108 HResult = info.GetInt32("HResult");
109 _source = info.GetString("Source");
112 // Get the WatsonBuckets that were serialized - this is particularly
113 // done to support exceptions going across AD transitions.
115 // We use the no throw version since we could be deserializing a pre-V4
116 // exception object that may not have this entry. In such a case, we would
118 _watsonBuckets = (Object)info.GetValueNoThrow("WatsonBuckets", typeof(byte[]));
121 #if FEATURE_SERIALIZATION
122 _safeSerializationManager = info.GetValueNoThrow("SafeSerializationManager", typeof(SafeSerializationManager)) as SafeSerializationManager;
123 #endif // FEATURE_SERIALIZATION
125 if (_className == null || HResult==0)
126 throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
128 // If we are constructing a new exception after a cross-appdomain call...
129 if (context.State == StreamingContextStates.CrossAppDomain)
131 // ...this new exception may get thrown. It is logically a re-throw, but
132 // physically a brand-new exception. Since the stack trace is cleared
133 // on a new exception, the "_remoteStackTraceString" is provided to
134 // effectively import a stack trace from a "remote" exception. So,
135 // move the _stackTraceString into the _remoteStackTraceString. Note
136 // that if there is an existing _remoteStackTraceString, it will be
137 // preserved at the head of the new string, so everything works as
139 // Even if this exception is NOT thrown, things will still work as expected
140 // because the StackTrace property returns the concatenation of the
141 // _remoteStackTraceString and the _stackTraceString.
142 _remoteStackTraceString = _remoteStackTraceString + _stackTraceString;
143 _stackTraceString = null;
148 public virtual String Message {
150 if (_message == null) {
151 if (_className==null) {
152 _className = GetClassName();
154 return Environment.GetResourceString("Exception_WasThrown", _className);
162 public virtual IDictionary Data {
163 [System.Security.SecuritySafeCritical] // auto-generated
166 if (IsImmutableAgileException(this))
167 _data = new EmptyReadOnlyDictionaryInternal();
169 _data = new ListDictionaryInternal();
176 private static bool IsImmutableAgileException(Exception e) { return false; }
178 [System.Security.SecurityCritical] // auto-generated
179 [ResourceExposure(ResourceScope.None)]
180 [MethodImplAttribute(MethodImplOptions.InternalCall)]
181 private static extern bool IsImmutableAgileException(Exception e);
184 #if FEATURE_COMINTEROP
186 // Exception requires anything to be added into Data dictionary is serializable
187 // This wrapper is made serializable to satisfy this requirement but does NOT serialize
188 // the object and simply ignores it during serialization, because we only need
189 // the exception instance in the app to hold the error object alive.
190 // Once the exception is serialized to debugger, debugger only needs the error reference string
193 internal class __RestrictedErrorObject
195 // Hold the error object instance but don't serialize/deserialize it
197 private object _realErrorObject;
199 internal __RestrictedErrorObject(object errorObject)
201 _realErrorObject = errorObject;
204 public object RealErrorObject
208 return _realErrorObject;
213 [FriendAccessAllowed]
214 internal void AddExceptionDataForRestrictedErrorInfo(
215 string restrictedError,
216 string restrictedErrorReference,
217 string restrictedCapabilitySid,
218 object restrictedErrorObject,
219 bool hasrestrictedLanguageErrorObject = false)
221 IDictionary dict = Data;
224 dict.Add("RestrictedDescription", restrictedError);
225 dict.Add("RestrictedErrorReference", restrictedErrorReference);
226 dict.Add("RestrictedCapabilitySid", restrictedCapabilitySid);
228 // Keep the error object alive so that user could retrieve error information
229 // using Data["RestrictedErrorReference"]
230 dict.Add("__RestrictedErrorObject", (restrictedErrorObject == null ? null : new __RestrictedErrorObject(restrictedErrorObject)));
231 dict.Add("__HasRestrictedLanguageErrorObject", hasrestrictedLanguageErrorObject);
235 internal bool TryGetRestrictedLanguageErrorObject(out object restrictedErrorObject)
237 restrictedErrorObject = null;
238 if (Data != null && Data.Contains("__HasRestrictedLanguageErrorObject"))
240 if (Data.Contains("__RestrictedErrorObject"))
242 __RestrictedErrorObject restrictedObject = Data["__RestrictedErrorObject"] as __RestrictedErrorObject;
243 if (restrictedObject != null)
244 restrictedErrorObject = restrictedObject.RealErrorObject;
246 return (bool)Data["__HasRestrictedLanguageErrorObject"];
251 #endif // FEATURE_COMINTEROP
253 private string GetClassName()
255 // Will include namespace but not full instantiation and assembly name.
256 if (_className == null)
257 _className = GetType().ToString();
262 // Retrieves the lowest exception (inner most) for the given Exception.
263 // This will traverse exceptions using the innerException property.
265 public virtual Exception GetBaseException()
267 Exception inner = InnerException;
268 Exception back = this;
270 while (inner != null) {
272 inner = inner.InnerException;
278 // Returns the inner exception contained in this exception
280 public Exception InnerException {
281 get { return _innerException; }
285 [System.Security.SecurityCritical] // auto-generated
286 [ResourceExposure(ResourceScope.None)]
287 [MethodImplAttribute(MethodImplOptions.InternalCall)]
288 static extern private IRuntimeMethodInfo GetMethodFromStackTrace(Object stackTrace);
291 [System.Security.SecuritySafeCritical] // auto-generated
292 private MethodBase GetExceptionMethodFromStackTrace()
294 IRuntimeMethodInfo method = GetMethodFromStackTrace(_stackTrace);
296 // Under certain race conditions when exceptions are re-used, this can be null
300 return RuntimeType.GetMethodBase(method);
304 public MethodBase TargetSite {
305 [System.Security.SecuritySafeCritical] // auto-generated
308 StackTrace st = new StackTrace (this, true);
309 if (st.FrameCount > 0)
310 return st.GetFrame (0).GetMethod ();
314 return GetTargetSiteInternal();
320 // This, as well as the entire "exception method" mechanism, appear to be linked to security features which Mono does not support.
321 // this function is provided as a private helper to avoid the security demand
322 [System.Security.SecurityCritical] // auto-generated
323 private MethodBase GetTargetSiteInternal() {
324 if (_exceptionMethod!=null) {
325 return _exceptionMethod;
327 if (_stackTrace==null) {
331 if (_exceptionMethodString!=null) {
332 _exceptionMethod = GetExceptionMethodFromString();
334 _exceptionMethod = GetExceptionMethodFromStackTrace();
336 return _exceptionMethod;
340 // Returns the stack trace as a string. If no stack trace is
341 // available, null is returned.
342 public virtual String StackTrace
345 [System.Security.SecuritySafeCritical]
349 // By default attempt to include file and line number info
350 return GetStackTrace(true);
354 // Computes and returns the stack trace as a string
355 // Attempts to get source file and line number information if needFileInfo
356 // is true. Note that this requires FileIOPermission(PathDiscovery), and so
357 // will usually fail in CoreCLR. To avoid the demand and resulting
358 // SecurityException we can explicitly not even try to get fileinfo.
360 [System.Security.SecurityCritical] // auto-generated
362 private string GetStackTrace(bool needFileInfo)
364 string stackTraceString = _stackTraceString;
365 string remoteStackTraceString = _remoteStackTraceString;
370 // Filter out file names/paths and line numbers from _stackTraceString and _remoteStackTraceString.
371 // This is used only when generating stack trace for Watson where the strings must be PII-free.
372 stackTraceString = StripFileInfo(stackTraceString, false);
373 remoteStackTraceString = StripFileInfo(remoteStackTraceString, true);
375 #endif // !FEATURE_CORECLR
377 // if no stack trace, try to get one
378 if (stackTraceString != null)
380 return remoteStackTraceString + stackTraceString;
382 if (_stackTrace == null)
384 return remoteStackTraceString;
387 // Obtain the stack trace string. Note that since Environment.GetStackTrace
388 // will add the path to the source file if the PDB is present and a demand
389 // for FileIOPermission(PathDiscovery) succeeds, we need to make sure we
390 // don't store the stack trace string in the _stackTraceString member variable.
391 String tempStackTraceString = Environment.GetStackTrace(this, needFileInfo);
392 return remoteStackTraceString + tempStackTraceString;
395 [FriendAccessAllowed]
396 internal void SetErrorCode(int hr)
401 // Sets the help link for this exception.
402 // This should be in a URL/URN form, such as:
403 // "file:///C:/Applications/Bazzal/help.html#ErrorNum42"
404 // Changed to be a read-write String and not return an exception
405 public virtual String HelpLink
417 public virtual String Source {
419 [System.Security.SecurityCritical] // auto-generated
424 StackTrace st = new StackTrace(this,true);
427 StackFrame sf = st.GetFrame(0);
428 MethodBase method = sf.GetMethod();
431 if (method != null) { // source can be null
432 _source = method.DeclaringType.Assembly.UnprotectedGetName ().Name;
435 Module module = method.Module;
437 RuntimeModule rtModule = module as RuntimeModule;
439 if (rtModule == null)
441 System.Reflection.Emit.ModuleBuilder moduleBuilder = module as System.Reflection.Emit.ModuleBuilder;
442 if (moduleBuilder != null)
443 rtModule = moduleBuilder.InternalModule;
445 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeReflectionObject"));
448 _source = rtModule.GetRuntimeAssembly().GetSimpleName();
456 [System.Security.SecurityCritical] // auto-generated
458 set { _source = value; }
462 [System.Security.SecuritySafeCritical]
464 public override String ToString()
466 return ToString(true, true);
470 [System.Security.SecurityCritical] // auto-generated
472 private String ToString(bool needFileLineInfo, bool needMessage) {
473 String message = (needMessage ? Message : null);
476 if (message == null || message.Length <= 0) {
480 s = GetClassName() + ": " + message;
483 if (_innerException!=null) {
484 s = s + " ---> " + _innerException.ToString(needFileLineInfo, needMessage) + Environment.NewLine +
485 " " + Environment.GetResourceString("Exception_EndOfInnerExceptionStack");
489 string stackTrace = GetStackTrace(needFileLineInfo);
490 if (stackTrace != null)
492 s += Environment.NewLine + stackTrace;
499 [System.Security.SecurityCritical] // auto-generated
500 private String GetExceptionMethodString() {
501 MethodBase methBase = GetTargetSiteInternal();
502 if (methBase==null) {
505 if (methBase is System.Reflection.Emit.DynamicMethod.RTDynamicMethod)
507 // DynamicMethods cannot be serialized
511 // Note that the newline separator is only a separator, chosen such that
512 // it won't (generally) occur in a method name. This string is used
513 // only for serialization of the Exception Method.
514 char separator = '\n';
515 StringBuilder result = new StringBuilder();
516 if (methBase is ConstructorInfo) {
517 RuntimeConstructorInfo rci = (RuntimeConstructorInfo)methBase;
518 Type t = rci.ReflectedType;
519 result.Append((int)MemberTypes.Constructor);
520 result.Append(separator);
521 result.Append(rci.Name);
524 result.Append(separator);
525 result.Append(t.Assembly.FullName);
526 result.Append(separator);
527 result.Append(t.FullName);
529 result.Append(separator);
530 result.Append(rci.ToString());
532 Contract.Assert(methBase is MethodInfo, "[Exception.GetExceptionMethodString]methBase is MethodInfo");
533 RuntimeMethodInfo rmi = (RuntimeMethodInfo)methBase;
534 Type t = rmi.DeclaringType;
535 result.Append((int)MemberTypes.Method);
536 result.Append(separator);
537 result.Append(rmi.Name);
538 result.Append(separator);
539 result.Append(rmi.Module.Assembly.FullName);
540 result.Append(separator);
543 result.Append(t.FullName);
544 result.Append(separator);
546 result.Append(rmi.ToString());
549 return result.ToString();
552 [System.Security.SecurityCritical] // auto-generated
553 private MethodBase GetExceptionMethodFromString() {
554 Contract.Assert(_exceptionMethodString != null, "Method string cannot be NULL!");
555 String[] args = _exceptionMethodString.Split(new char[]{'\0', '\n'});
556 if (args.Length!=5) {
557 throw new SerializationException();
559 SerializationInfo si = new SerializationInfo(typeof(MemberInfoSerializationHolder), new FormatterConverter());
560 si.AddValue("MemberType", (int)Int32.Parse(args[0], CultureInfo.InvariantCulture), typeof(Int32));
561 si.AddValue("Name", args[1], typeof(String));
562 si.AddValue("AssemblyName", args[2], typeof(String));
563 si.AddValue("ClassName", args[3]);
564 si.AddValue("Signature", args[4]);
566 StreamingContext sc = new StreamingContext(StreamingContextStates.All);
568 result = (MethodBase)new MemberInfoSerializationHolder(si, sc).GetRealObject(sc);
569 } catch (SerializationException) {
576 #if FEATURE_SERIALIZATION
577 protected event EventHandler<SafeSerializationEventArgs> SerializeObjectState
579 add { _safeSerializationManager.SerializeObjectState += value; }
580 remove { _safeSerializationManager.SerializeObjectState -= value; }
582 #endif // FEATURE_SERIALIZATION
584 [System.Security.SecurityCritical] // auto-generated_required
585 public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
589 throw new ArgumentNullException("info");
591 Contract.EndContractBlock();
593 String tempStackTraceString = _stackTraceString;
595 if (_stackTrace!=null)
597 if (tempStackTraceString==null)
599 tempStackTraceString = Environment.GetStackTrace(this, true);
602 if (_exceptionMethod==null)
604 _exceptionMethod = GetExceptionMethodFromStackTrace();
611 _source = Source; // Set the Source information correctly before serialization
614 info.AddValue("ClassName", GetClassName(), typeof(String));
615 info.AddValue("Message", _message, typeof(String));
616 info.AddValue("Data", _data, typeof(IDictionary));
617 info.AddValue("InnerException", _innerException, typeof(Exception));
618 info.AddValue("HelpURL", _helpURL, typeof(String));
619 info.AddValue("StackTraceString", tempStackTraceString, typeof(String));
620 info.AddValue("RemoteStackTraceString", _remoteStackTraceString, typeof(String));
621 info.AddValue("RemoteStackIndex", _remoteStackIndex, typeof(Int32));
623 info.AddValue("ExceptionMethod", null);
625 info.AddValue("ExceptionMethod", GetExceptionMethodString(), typeof(String));
627 info.AddValue("HResult", HResult);
628 info.AddValue("Source", _source, typeof(String));
631 // Serialize the Watson bucket details as well
632 info.AddValue("WatsonBuckets", _watsonBuckets, typeof(byte[]));
635 #if FEATURE_SERIALIZATION
636 if (_safeSerializationManager != null && _safeSerializationManager.IsActive)
638 info.AddValue("SafeSerializationManager", _safeSerializationManager, typeof(SafeSerializationManager));
640 // User classes derived from Exception must have a valid _safeSerializationManager.
641 // Exceptions defined in mscorlib don't use this field might not have it initalized (since they are
642 // often created in the VM with AllocateObject instead if the managed construtor)
643 // If you are adding code to use a SafeSerializationManager from an mscorlib exception, update
644 // this assert to ensure that it fails when that exception's _safeSerializationManager is NULL
645 Contract.Assert(((_safeSerializationManager != null) || (this.GetType().Assembly == typeof(object).Assembly)),
646 "User defined exceptions must have a valid _safeSerializationManager");
648 // Handle serializing any transparent or partial trust subclass data
649 _safeSerializationManager.CompleteSerialization(this, info, context);
651 #endif // FEATURE_SERIALIZATION
654 // This is used by remoting to preserve the server side stack trace
655 // by appending it to the message ... before the exception is rethrown
656 // at the client call site.
657 internal Exception PrepForRemoting()
661 if (_remoteStackIndex == 0)
663 tmp = Environment.NewLine+ "Server stack trace: " + Environment.NewLine
665 + Environment.NewLine + Environment.NewLine
666 + "Exception rethrown at ["+_remoteStackIndex+"]: " + Environment.NewLine;
671 + Environment.NewLine + Environment.NewLine
672 + "Exception rethrown at ["+_remoteStackIndex+"]: " + Environment.NewLine;
675 _remoteStackTraceString = tmp;
681 // This method will clear the _stackTrace of the exception object upon deserialization
682 // to ensure that references from another AD/Process dont get accidently used.
684 private void OnDeserialized(StreamingContext context)
689 // We wont serialize or deserialize the IP for Watson bucketing since
690 // we dont know where the deserialized object will be used in.
691 // Using it across process or an AppDomain could be invalid and result
692 // in AV in the runtime.
694 // Hence, we set it to zero when deserialization takes place.
695 _ipForWatsonBuckets = UIntPtr.Zero;
698 #if FEATURE_SERIALIZATION
699 if (_safeSerializationManager == null)
701 _safeSerializationManager = new SafeSerializationManager();
705 _safeSerializationManager.CompleteDeserialization(this);
707 #endif // FEATURE_SERIALIZATION
710 // This is used by the runtime when re-throwing a managed exception. It will
711 // copy the stack trace to _remoteStackTraceString.
713 [System.Security.SecuritySafeCritical]
715 internal void InternalPreserveStackTrace()
717 string tmpStackTraceString;
720 if (AppDomain.IsAppXModel())
722 // Call our internal GetStackTrace in AppX so we can parse the result should
723 // we need to strip file/line info from it to make it PII-free. Calling the
724 // public and overridable StackTrace getter here was probably not intended.
725 tmpStackTraceString = GetStackTrace(true);
727 // Make sure that the _source field is initialized if Source is not overriden.
728 // We want it to contain the original faulting point.
729 string source = Source;
732 #else // FEATURE_APPX
733 #if FEATURE_CORESYSTEM
734 // Preinitialize _source on CoreSystem as well. The legacy behavior is not ideal and
735 // we keep it for back compat but we can afford to make the change on the Phone.
736 string source = Source;
737 #endif // FEATURE_CORESYSTEM
738 #endif // FEATURE_APPX
740 // Call the StackTrace getter in classic for compat.
741 tmpStackTraceString = StackTrace;
744 if (tmpStackTraceString != null && tmpStackTraceString.Length > 0)
746 _remoteStackTraceString = tmpStackTraceString + Environment.NewLine;
750 _stackTraceString = null;
753 #if FEATURE_EXCEPTIONDISPATCHINFO
755 // This is the object against which a lock will be taken
756 // when attempt to restore the EDI. Since its static, its possible
757 // that unrelated exception object restorations could get blocked
758 // for a small duration but that sounds reasonable considering
759 // such scenarios are going to be extremely rare, where timing
760 // matches precisely.
762 private static object s_EDILock = new object();
765 internal UIntPtr IPForWatsonBuckets
768 return _ipForWatsonBuckets;
772 internal object WatsonBuckets
776 return _watsonBuckets;
781 internal string RemoteStackTrace
785 return _remoteStackTraceString;
790 // This is only needed for Watson support
791 private string StripFileInfo(string stackTrace, bool isRemoteStackTrace) {
795 [System.Security.SecurityCritical] // auto-generated
796 [ResourceExposure(ResourceScope.None)]
797 [MethodImplAttribute(MethodImplOptions.InternalCall)]
798 private static extern void PrepareForForeignExceptionRaise();
800 [System.Security.SecurityCritical] // auto-generated
801 [ResourceExposure(ResourceScope.None)]
802 [MethodImplAttribute(MethodImplOptions.InternalCall)]
803 private static extern void GetStackTracesDeepCopy(Exception exception, out object currentStackTrace, out object dynamicMethodArray);
805 [System.Security.SecurityCritical] // auto-generated
806 [ResourceExposure(ResourceScope.None)]
807 [MethodImplAttribute(MethodImplOptions.InternalCall)]
808 internal static extern void SaveStackTracesFromDeepCopy(Exception exception, object currentStackTrace, object dynamicMethodArray);
810 [System.Security.SecurityCritical] // auto-generated
811 [ResourceExposure(ResourceScope.None)]
812 [MethodImplAttribute(MethodImplOptions.InternalCall)]
813 private static extern object CopyStackTrace(object currentStackTrace);
815 [System.Security.SecurityCritical] // auto-generated
816 [ResourceExposure(ResourceScope.None)]
817 [MethodImplAttribute(MethodImplOptions.InternalCall)]
818 private static extern object CopyDynamicMethods(object currentDynamicMethods);
821 [System.Security.SecuritySafeCritical]
822 [ResourceExposure(ResourceScope.None)]
823 [MethodImplAttribute(MethodImplOptions.InternalCall)]
824 private extern string StripFileInfo(string stackTrace, bool isRemoteStackTrace);
825 #endif // !FEATURE_CORECLR
827 [SecuritySafeCritical]
828 internal object DeepCopyStackTrace(object currentStackTrace)
830 if (currentStackTrace != null)
832 return CopyStackTrace(currentStackTrace);
840 [SecuritySafeCritical]
841 internal object DeepCopyDynamicMethods(object currentDynamicMethods)
843 if (currentDynamicMethods != null)
845 return CopyDynamicMethods(currentDynamicMethods);
853 [SecuritySafeCritical]
854 internal void GetStackTracesDeepCopy(out object currentStackTrace, out object dynamicMethodArray)
856 GetStackTracesDeepCopy(this, out currentStackTrace, out dynamicMethodArray);
860 // This is invoked by ExceptionDispatchInfo.Throw to restore the exception stack trace, corresponding to the original throw of the
861 // exception, just before the exception is "rethrown".
862 [SecuritySafeCritical]
863 internal void RestoreExceptionDispatchInfo(System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo)
866 captured_traces = (StackTrace[]) exceptionDispatchInfo.BinaryStackTraceArray;
868 _stackTraceString = null;
870 bool fCanProcessException = !(IsImmutableAgileException(this));
871 // Restore only for non-preallocated exceptions
872 if (fCanProcessException)
874 // Take a lock to ensure only one thread can restore the details
875 // at a time against this exception object that could have
876 // multiple ExceptionDispatchInfo instances associated with it.
878 // We do this inside a finally clause to ensure ThreadAbort cannot
879 // be injected while we have taken the lock. This is to prevent
880 // unrelated exception restorations from getting blocked due to TAE.
884 // When restoring back the fields, we again create a copy and set reference to them
885 // in the exception object. This will ensure that when this exception is thrown and these
886 // fields are modified, then EDI's references remain intact.
888 // Since deep copying can throw on OOM, try to get the copies
890 object _stackTraceCopy = (exceptionDispatchInfo.BinaryStackTraceArray == null)?null:DeepCopyStackTrace(exceptionDispatchInfo.BinaryStackTraceArray);
891 object _dynamicMethodsCopy = (exceptionDispatchInfo.DynamicMethodArray == null)?null:DeepCopyDynamicMethods(exceptionDispatchInfo.DynamicMethodArray);
893 // Finally, restore the information.
895 // Since EDI can be created at various points during exception dispatch (e.g. at various frames on the stack) for the same exception instance,
896 // they can have different data to be restored. Thus, to ensure atomicity of restoration from each EDI, perform the restore under a lock.
897 lock(Exception.s_EDILock)
900 _watsonBuckets = exceptionDispatchInfo.WatsonBuckets;
901 _ipForWatsonBuckets = exceptionDispatchInfo.IPForWatsonBuckets;
903 _remoteStackTraceString = exceptionDispatchInfo.RemoteStackTrace;
904 SaveStackTracesFromDeepCopy(this, _stackTraceCopy, _dynamicMethodsCopy);
906 _stackTraceString = null;
908 // Marks the TES state to indicate we have restored foreign exception
909 // dispatch information.
910 Exception.PrepareForForeignExceptionRaise();
915 #endif // FEATURE_EXCEPTIONDISPATCHINFO
917 private String _className; //Needed for serialization.
919 // See TargetSite comments
920 private MethodBase _exceptionMethod; //Needed for serialization.
921 private String _exceptionMethodString; //Needed for serialization.
923 internal String _message;
924 private IDictionary _data;
925 private Exception _innerException;
926 private String _helpURL;
927 private Object _stackTrace;
929 // Watson is Microsoft's online crash reporting system
930 [OptionalField] // This isnt present in pre-V4 exception objects that would be serialized.
931 private Object _watsonBuckets;
933 private String _stackTraceString; //Needed for serialization.
934 private String _remoteStackTraceString;
935 private int _remoteStackIndex;
936 #pragma warning disable 414 // Field is not used from managed.
937 // _dynamicMethods is an array of System.Resolver objects, used to keep
938 // DynamicMethodDescs alive for the lifetime of the exception. We do this because
939 // the _stackTrace field holds MethodDescs, and a DynamicMethodDesc can be destroyed
940 // unless a System.Resolver object roots it.
941 private Object _dynamicMethods;
942 #pragma warning restore 414
944 // @MANAGED: HResult is used from within the EE! Rename with care - check VM directory
945 internal int _HResult; // HResult
959 private String _source; // Mainly used by VB.
961 // WARNING: Don't delete/rename _xptrs and _xcode - used by functions
962 // on Marshal class. Native functions are in COMUtilNative.cpp & AppDomain
963 private IntPtr _xptrs; // Internal EE stuff
964 #pragma warning disable 414 // Field is not used from managed.
965 private int _xcode; // Internal EE stuff
966 #pragma warning restore 414
968 private UIntPtr _ipForWatsonBuckets; // Used to persist the IP for Watson Bucketing
971 #if FEATURE_SERIALIZATION
972 [OptionalField(VersionAdded = 4)]
973 private SafeSerializationManager _safeSerializationManager;
974 #endif // FEATURE_SERIALIZATION
977 // Mono: Used when rethrowing exception
978 internal StackTrace[] captured_traces;
980 // Mono addition: Used on iPhone
981 IntPtr[] native_trace_ips;
984 // See clr\src\vm\excep.h's EXCEPTION_COMPLUS definition:
985 private const int _COMPlusExceptionCode = unchecked((int)0xe0434352); // Win32 exception code for COM+ exceptions
987 // InternalToString is called by the runtime to get the exception text
988 // and create a corresponding CrossAppDomainMarshaledException
989 [System.Security.SecurityCritical] // auto-generated
990 internal virtual String InternalToString()
995 #pragma warning disable 618
996 SecurityPermission sp= new SecurityPermission(SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy);
997 #pragma warning restore 618
1002 //under normal conditions there should be no exceptions
1003 //however if something wrong happens we still can call the usual ToString
1007 // Get the current stack trace string. On CoreCLR we don't bother
1008 // to try and include file/line-number information because all AppDomains
1009 // are sandboxed, and so this won't succeed in most (or all) cases. Therefore the
1010 // Demand and exception overhead is a waste.
1011 // We currently have some bugs in watson bucket generation where the SecurityException
1012 // here causes us to lose saved bucket parameters. By not even doing the demand
1013 // we avoid those problems (although there are deep underlying problems that need to
1014 // be fixed there - relying on this to avoid problems is incomplete and brittle).
1015 bool fGetFileLineInfo = true;
1017 fGetFileLineInfo = false;
1019 return ToString(fGetFileLineInfo, true);
1022 #if !FEATURE_CORECLR
1023 // this method is required so Object.GetType is not made virtual by the compiler
1024 // _Exception.GetType()
1025 public new Type GetType()
1027 return base.GetType();
1031 internal bool IsTransient
1033 [System.Security.SecuritySafeCritical] // auto-generated
1035 return nIsTransient(_HResult);
1039 [System.Security.SecurityCritical] // auto-generated
1040 [ResourceExposure(ResourceScope.None)]
1041 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1042 private extern static bool nIsTransient(int hr);
1045 // This piece of infrastructure exists to help avoid deadlocks
1046 // between parts of mscorlib that might throw an exception while
1047 // holding a lock that are also used by mscorlib's ResourceManager
1048 // instance. As a special case of code that may throw while holding
1049 // a lock, we also need to fix our asynchronous exceptions to use
1050 // Win32 resources as well (assuming we ever call a managed
1051 // constructor on instances of them). We should grow this set of
1052 // exception messages as we discover problems, then move the resources
1053 // involved to native code.
1054 internal enum ExceptionMessageKind
1057 ThreadInterrupted = 2,
1061 // See comment on ExceptionMessageKind
1062 [System.Security.SecuritySafeCritical] // auto-generated
1063 internal static String GetMessageFromNativeResources(ExceptionMessageKind kind)
1067 case ExceptionMessageKind.ThreadAbort:
1069 case ExceptionMessageKind.ThreadInterrupted:
1071 case ExceptionMessageKind.OutOfMemory:
1072 return "Out of memory";
1076 string retMesg = null;
1077 GetMessageFromNativeResources(kind, JitHelpers.GetStringHandleOnStack(ref retMesg));
1083 [System.Security.SecurityCritical] // auto-generated
1084 [ResourceExposure(ResourceScope.None)]
1085 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
1086 [SuppressUnmanagedCodeSecurity]
1087 private static extern void GetMessageFromNativeResources(ExceptionMessageKind kind, StringHandleOnStack retMesg);
1091 // Exposed to support Mono BCL classes
1092 internal void SetMessage (string s)
1097 internal void SetStackTrace (string s)
1099 _stackTraceString = s;
1102 // Support for a System.Runtime.Remoting.Proxies.RealProxy edge case
1103 internal Exception FixRemotingException ()
1105 string message = (0 == _remoteStackIndex) ?
1106 Locale.GetText ("{0}{0}Server stack trace: {0}{1}{0}{0}Exception rethrown at [{2}]: {0}") :
1107 Locale.GetText ("{1}{0}{0}Exception rethrown at [{2}]: {0}");
1108 string tmp = String.Format (message, Environment.NewLine, StackTrace, _remoteStackIndex);
1110 _remoteStackTraceString = tmp;
1111 _remoteStackIndex++;
1113 _stackTraceString = null;
1124 //--------------------------------------------------------------------------
1125 // Telesto: Telesto doesn't support appdomain marshaling of objects so
1126 // managed exceptions that leak across appdomain boundaries are flatted to
1127 // its ToString() output and rethrown as an CrossAppDomainMarshaledException.
1128 // The Message field is set to the ToString() output of the original exception.
1129 //--------------------------------------------------------------------------
1132 internal sealed class CrossAppDomainMarshaledException : SystemException
1134 public CrossAppDomainMarshaledException(String message, int errorCode)
1137 SetErrorCode(errorCode);
1140 // Normally, only Telesto's UEF will see these exceptions.
1141 // This override prints out the original Exception's ToString()
1142 // output and hides the fact that it is wrapped inside another excepton.
1144 [System.Security.SecurityCritical] // auto-generated
1146 internal override String InternalToString()