3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*=============================================================================
8 ** File: ExceptionServicesCommon.cs
11 ** Purpose: Contains common usage support entities for advanced exception
12 ** handling/processing scenarios.
16 ** <owner>Microsoft</owner>
18 =============================================================================*/
20 #if FEATURE_EXCEPTIONDISPATCHINFO
21 namespace System.Runtime.ExceptionServices {
24 // This class defines support for seperating the exception dispatch details
25 // (like stack trace, watson buckets, etc) from the actual managed exception
26 // object. This allows us to track error (via the exception object) independent
27 // of the path the error takes.
29 // This is particularly useful for frameworks like PFX, APM, etc that wish to
30 // propagate exceptions (i.e. errors to be precise) across threads.
31 public sealed class ExceptionDispatchInfo
33 // Private members that will hold the relevant details.
34 private Exception m_Exception;
36 private string m_remoteStackTrace;
38 private object m_stackTrace;
40 private object m_dynamicMethods;
41 private UIntPtr m_IPForWatsonBuckets;
42 private Object m_WatsonBuckets;
45 private ExceptionDispatchInfo(Exception exception)
47 // Copy over the details we need to save.
48 m_Exception = exception;
50 var count = exception.captured_traces == null ? 0 : exception.captured_traces.Length;
51 var stack_traces = new System.Diagnostics.StackTrace [count + 1];
53 Array.Copy (exception.captured_traces, 0, stack_traces, 0, count);
55 stack_traces [count] = new System.Diagnostics.StackTrace (exception, 0, true);
56 m_stackTrace = stack_traces;
58 m_remoteStackTrace = exception.RemoteStackTrace;
60 // NOTE: don't be tempted to pass the fields for the out params; the containing object
61 // might be relocated during the call so the pointers will no longer be valid.
63 object dynamicMethods;
64 m_Exception.GetStackTracesDeepCopy(out stackTrace, out dynamicMethods);
65 m_stackTrace = stackTrace;
66 m_dynamicMethods = dynamicMethods;
68 m_IPForWatsonBuckets = exception.IPForWatsonBuckets;
69 m_WatsonBuckets = exception.WatsonBuckets;
74 internal UIntPtr IPForWatsonBuckets
78 return m_IPForWatsonBuckets;
82 internal object WatsonBuckets
86 return m_WatsonBuckets;
91 internal object BinaryStackTraceArray
100 internal object DynamicMethodArray
104 return m_dynamicMethods;
108 internal string RemoteStackTrace
112 return m_remoteStackTrace;
117 // This static method is used to create an instance of ExceptionDispatchInfo for
118 // the specified exception object and save all the required details that maybe
119 // needed to be propagated when the exception is "rethrown" on a different thread.
120 public static ExceptionDispatchInfo Capture(Exception source)
124 throw new ArgumentNullException("source", Environment.GetResourceString("ArgumentNull_Obj"));
127 return new ExceptionDispatchInfo(source);
130 // Return the exception object represented by this ExceptionDispatchInfo instance
131 public Exception SourceException
140 // When a framework needs to "Rethrow" an exception on a thread different (but not necessarily so) from
141 // where it was thrown, it should invoke this method against the ExceptionDispatchInfo (EDI)
142 // created for the exception in question.
144 // This method will restore the original stack trace and bucketing details before throwing
145 // the exception so that it is easy, from debugging standpoint, to understand what really went wrong on
146 // the original thread.
149 // Restore the exception dispatch details before throwing the exception.
150 m_Exception.RestoreExceptionDispatchInfo(this);
155 #endif // FEATURE_EXCEPTIONDISPATCHINFO