summaryrefslogtreecommitdiff
path: root/src/vm/exinfo.h
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__