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