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#ifndef _EEDBGINTERFACEIMPL_INL_
9#define _EEDBGINTERFACEIMPL_INL_
10
11#include "common.h"
12
13
14// This class only serves as a wrapper for the debugger callbacks.
15// Using this class eliminates the need to check "#ifdef DEBUGGING_SUPPORTED"
16// and "CORDebuggerAttached()".
17class EEToDebuggerExceptionInterfaceWrapper
18{
19 public:
20
21#if defined(DEBUGGING_SUPPORTED) && !defined(DACCESS_COMPILE)
22 static inline bool FirstChanceManagedException(Thread* pThread, SIZE_T currentIP, SIZE_T currentSP)
23 {
24 CONTRACTL
25 {
26 THROWS;
27 GC_TRIGGERS;
28 SO_INTOLERANT;
29 MODE_ANY;
30 }
31 CONTRACTL_END;
32
33 ThreadExceptionState* pExState = pThread->GetExceptionState();
34 pExState->GetDebuggerState()->SetDebuggerIndicatedFramePointer((LPVOID)currentSP);
35
36 if (CORDebuggerAttached())
37 {
38 // Notfiy the debugger that we are on the first pass for a managed exception.
39 // Note that this callback is made for every managed frame.
40 return g_pDebugInterface->FirstChanceManagedException(pThread, currentIP, currentSP);
41 }
42 else
43 {
44 return false;
45 }
46 }
47
48 static inline void FirstChanceManagedExceptionCatcherFound(Thread* pThread, MethodDesc* pMD, TADDR pMethodAddr, SIZE_T currentSP,
49 EE_ILEXCEPTION_CLAUSE* pEHClause)
50 {
51 CONTRACTL
52 {
53 THROWS;
54 GC_TRIGGERS;
55 SO_INTOLERANT;
56 MODE_ANY;
57 }
58 CONTRACTL_END;
59
60
61 ThreadExceptionState* pExState = pThread->GetExceptionState();
62 pExState->GetDebuggerState()->SetDebuggerIndicatedFramePointer((LPVOID)currentSP);
63
64 if (CORDebuggerAttached())
65 {
66 g_pDebugInterface->FirstChanceManagedExceptionCatcherFound(pThread, pMD, pMethodAddr, (PBYTE)currentSP,
67 pEHClause);
68 }
69 }
70
71 static inline void NotifyOfCHFFilter(EXCEPTION_POINTERS * pExceptionInfo, Frame * pFrame)
72 {
73 WRAPPER_NO_CONTRACT;
74
75 if (CORDebuggerAttached())
76 {
77 g_pDebugInterface->NotifyOfCHFFilter(pExceptionInfo, pFrame);
78 }
79 }
80
81 static inline void ManagedExceptionUnwindBegin(Thread* pThread)
82 {
83 WRAPPER_NO_CONTRACT;
84
85 if (CORDebuggerAttached())
86 {
87 g_pDebugInterface->ManagedExceptionUnwindBegin(pThread);
88 }
89 }
90
91 static inline void ExceptionFilter(MethodDesc* pMD, TADDR pMethodAddr, SIZE_T offset, BYTE* pStack)
92 {
93 WRAPPER_NO_CONTRACT;
94
95 if (CORDebuggerAttached())
96 {
97 g_pDebugInterface->ExceptionFilter(pMD, pMethodAddr, offset, pStack);
98 }
99 }
100
101 static inline void ExceptionHandle(MethodDesc* pMD, TADDR pMethodAddr, SIZE_T offset, BYTE* pStack)
102 {
103 WRAPPER_NO_CONTRACT;
104
105 if (CORDebuggerAttached())
106 {
107 g_pDebugInterface->ExceptionHandle(pMD, pMethodAddr, offset, pStack);
108 }
109 }
110
111#else // !defined(DEBUGGING_SUPPORTED) || defined(DACCESS_COMPILE)
112 static inline bool FirstChanceManagedException(Thread* pThread, SIZE_T currentIP, SIZE_T currentSP) {LIMITED_METHOD_CONTRACT; return false;}
113 static inline void FirstChanceManagedExceptionCatcherFound(Thread* pThread, MethodDesc* pMD, TADDR pMethodAddr, BYTE* currentSP,
114 EE_ILEXCEPTION_CLAUSE* pEHClause) {LIMITED_METHOD_CONTRACT;}
115 static inline void ManagedExceptionUnwindBegin(Thread* pThread) {LIMITED_METHOD_CONTRACT;}
116 static inline void ExceptionFilter(MethodDesc* pMD, TADDR pMethodAddr, SIZE_T offset, BYTE* pStack) {LIMITED_METHOD_CONTRACT;}
117 static inline void ExceptionHandle(MethodDesc* pMD, TADDR pMethodAddr, SIZE_T offset, BYTE* pStack) {LIMITED_METHOD_CONTRACT;}
118#endif // !defined(DEBUGGING_SUPPORTED) || defined(DACCESS_COMPILE)
119};
120
121
122#endif // _EEDBGINTERFACEIMPL_INL_
123