1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | // |
5 | |
6 | // |
7 | |
8 | |
9 | #ifndef __ExInfo_h__ |
10 | #define __ExInfo_h__ |
11 | #if !defined(WIN64EXCEPTIONS) |
12 | |
13 | #include "exstatecommon.h" |
14 | |
15 | typedef DPTR(class ExInfo) PTR_ExInfo; |
16 | class ExInfo |
17 | { |
18 | friend class ThreadExceptionState; |
19 | friend class ClrDataExceptionState; |
20 | |
21 | public: |
22 | |
23 | BOOL IsHeapAllocated() |
24 | { |
25 | LIMITED_METHOD_CONTRACT; |
26 | return m_StackAddress != (void *) this; |
27 | } |
28 | |
29 | void CopyAndClearSource(ExInfo *from); |
30 | |
31 | void UnwindExInfo(VOID* limit); |
32 | |
33 | // Q: Why does this thing take an EXCEPTION_RECORD rather than an ExceptionCode? |
34 | // A: Because m_ExceptionCode and Ex_WasThrownByUs have to be kept |
35 | // in sync and this function needs the exception parms inside the record to figure |
36 | // out the "IsTagged" part. |
37 | void SetExceptionCode(const EXCEPTION_RECORD *pCER); |
38 | |
39 | DWORD GetExceptionCode() |
40 | { |
41 | LIMITED_METHOD_CONTRACT; |
42 | return m_ExceptionCode; |
43 | } |
44 | |
45 | public: // @TODO: make more of these private! |
46 | // Note: the debugger assumes that m_pThrowable is a strong |
47 | // reference so it can check it for NULL with preemptive GC |
48 | // enabled. |
49 | OBJECTHANDLE m_hThrowable; // thrown exception |
50 | PTR_Frame m_pSearchBoundary; // topmost frame for current managed frame group |
51 | private: |
52 | DWORD m_ExceptionCode; // After a catch of a COM+ exception, pointers/context are trashed. |
53 | public: |
54 | PTR_EXCEPTION_REGISTRATION_RECORD m_pBottomMostHandler; // most recent EH record registered |
55 | |
56 | // Reference to the topmost handler we saw during an SO that goes past us |
57 | PTR_EXCEPTION_REGISTRATION_RECORD m_pTopMostHandlerDuringSO; |
58 | |
59 | LPVOID m_dEsp; // Esp when fault occurred, OR esp to restore on endcatch |
60 | |
61 | StackTraceInfo m_StackTraceInfo; |
62 | |
63 | PTR_ExInfo m_pPrevNestedInfo; // pointer to nested info if are handling nested exception |
64 | |
65 | size_t* m_pShadowSP; // Zero this after endcatch |
66 | |
67 | PTR_EXCEPTION_RECORD m_pExceptionRecord; |
68 | PTR_EXCEPTION_POINTERS m_pExceptionPointers; |
69 | PTR_CONTEXT m_pContext; |
70 | |
71 | // We have a rare case where (re-entry to the EE from an unmanaged filter) where we |
72 | // need to create a new ExInfo ... but don't have a nested handler for it. The handlers |
73 | // use stack addresses to figure out their correct lifetimes. This stack location is |
74 | // used for that. For most records, it will be the stack address of the ExInfo ... but |
75 | // for some records, it will be a pseudo stack location -- the place where we think |
76 | // the record should have been (except for the re-entry case). |
77 | // |
78 | // |
79 | // |
80 | void* m_StackAddress; // A pseudo or real stack location for this record. |
81 | |
82 | #ifndef FEATURE_PAL |
83 | private: |
84 | EHWatsonBucketTracker m_WatsonBucketTracker; |
85 | public: |
86 | inline PTR_EHWatsonBucketTracker GetWatsonBucketTracker() |
87 | { |
88 | LIMITED_METHOD_CONTRACT; |
89 | return PTR_EHWatsonBucketTracker(PTR_HOST_MEMBER_TADDR(ExInfo, this, m_WatsonBucketTracker)); |
90 | } |
91 | #endif |
92 | |
93 | #ifdef FEATURE_CORRUPTING_EXCEPTIONS |
94 | private: |
95 | CorruptionSeverity m_CorruptionSeverity; |
96 | public: |
97 | inline CorruptionSeverity GetCorruptionSeverity() |
98 | { |
99 | LIMITED_METHOD_CONTRACT; |
100 | |
101 | return (CorruptionSeverity)GET_CORRUPTION_SEVERITY(m_CorruptionSeverity); |
102 | } |
103 | |
104 | inline void SetCorruptionSeverity(CorruptionSeverity severityToSet) |
105 | { |
106 | LIMITED_METHOD_CONTRACT; |
107 | |
108 | m_CorruptionSeverity = severityToSet; |
109 | } |
110 | #endif // FEATURE_CORRUPTING_EXCEPTIONS |
111 | |
112 | private: |
113 | BOOL m_fDeliveredFirstChanceNotification; |
114 | public: |
115 | inline BOOL DeliveredFirstChanceNotification() |
116 | { |
117 | LIMITED_METHOD_CONTRACT; |
118 | |
119 | return m_fDeliveredFirstChanceNotification; |
120 | } |
121 | |
122 | inline void SetFirstChanceNotificationStatus(BOOL fDelivered) |
123 | { |
124 | LIMITED_METHOD_CONTRACT; |
125 | |
126 | m_fDeliveredFirstChanceNotification = fDelivered; |
127 | } |
128 | |
129 | // Returns the exception tracker previous to the current |
130 | inline PTR_ExInfo GetPreviousExceptionTracker() |
131 | { |
132 | LIMITED_METHOD_CONTRACT; |
133 | |
134 | return m_pPrevNestedInfo; |
135 | } |
136 | |
137 | // Returns the throwable associated with the tracker |
138 | inline OBJECTREF GetThrowable() |
139 | { |
140 | LIMITED_METHOD_CONTRACT; |
141 | |
142 | return (m_hThrowable != NULL)?ObjectFromHandle(m_hThrowable):NULL; |
143 | } |
144 | |
145 | // Returns the throwble associated with the tracker as handle |
146 | inline OBJECTHANDLE GetThrowableAsHandle() |
147 | { |
148 | LIMITED_METHOD_CONTRACT; |
149 | |
150 | return m_hThrowable; |
151 | } |
152 | |
153 | public: |
154 | |
155 | DebuggerExState m_DebuggerExState; |
156 | EHClauseInfo m_EHClauseInfo; |
157 | ExceptionFlags m_ExceptionFlags; |
158 | |
159 | #if defined(_TARGET_X86_) && defined(DEBUGGING_SUPPORTED) |
160 | EHContext m_InterceptionContext; |
161 | BOOL m_ValidInterceptionContext; |
162 | #endif |
163 | |
164 | #ifdef DACCESS_COMPILE |
165 | void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); |
166 | #endif |
167 | |
168 | void Init(); |
169 | ExInfo() DAC_EMPTY(); |
170 | |
171 | void DestroyExceptionHandle(); |
172 | |
173 | private: |
174 | // Don't allow this |
175 | ExInfo& operator=(const ExInfo &from); |
176 | }; |
177 | |
178 | #if defined(_TARGET_X86_) |
179 | PTR_ExInfo GetEHTrackerForPreallocatedException(OBJECTREF oPreAllocThrowable, PTR_ExInfo pStartingEHTracker); |
180 | #endif // _TARGET_X86_ |
181 | |
182 | #endif // !WIN64EXCEPTIONS |
183 | #endif // __ExInfo_h__ |
184 | |