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 | ** Header: DebugDebugger.h |
8 | ** |
9 | ** Purpose: Native methods on System.Debug.Debugger |
10 | ** |
11 | ** |
12 | |
13 | ===========================================================*/ |
14 | |
15 | #ifndef __DEBUG_DEBUGGER_h__ |
16 | #define __DEBUG_DEBUGGER_h__ |
17 | #include <object.h> |
18 | |
19 | |
20 | class DebugDebugger |
21 | { |
22 | public: |
23 | static FCDECL0(void, Break); |
24 | static FCDECL0(FC_BOOL_RET, Launch); |
25 | static FCDECL0(FC_BOOL_RET, IsDebuggerAttached); |
26 | static FCDECL3(void, Log, INT32 Level, StringObject* strModule, StringObject* strMessage); |
27 | |
28 | // receives a custom notification object from the target and sends it to the RS via |
29 | // code:Debugger::SendCustomDebuggerNotification |
30 | static FCDECL1(void, CustomNotification, Object * dataUNSAFE); |
31 | |
32 | static FCDECL0(FC_BOOL_RET, IsLogging); |
33 | |
34 | protected: |
35 | static BOOL IsLoggingHelper(); |
36 | }; |
37 | |
38 | |
39 | class StackFrameHelper : public Object |
40 | { |
41 | // READ ME: |
42 | // Modifying the order or fields of this object may require other changes to the |
43 | // classlib defintion of the StackFrameHelper class. |
44 | public: |
45 | THREADBASEREF targetThread; |
46 | I4ARRAYREF rgiOffset; |
47 | I4ARRAYREF rgiILOffset; |
48 | PTRARRAYREF dynamicMethods; |
49 | BASEARRAYREF rgMethodHandle; |
50 | PTRARRAYREF rgAssemblyPath; |
51 | BASEARRAYREF rgLoadedPeAddress; |
52 | I4ARRAYREF rgiLoadedPeSize; |
53 | BASEARRAYREF rgInMemoryPdbAddress; |
54 | I4ARRAYREF rgiInMemoryPdbSize; |
55 | // if rgiMethodToken[i] == 0, then don't attempt to get the portable PDB source/info |
56 | I4ARRAYREF rgiMethodToken; |
57 | PTRARRAYREF rgFilename; |
58 | I4ARRAYREF rgiLineNumber; |
59 | I4ARRAYREF rgiColumnNumber; |
60 | |
61 | BOOLARRAYREF rgiLastFrameFromForeignExceptionStackTrace; |
62 | |
63 | int iFrameCount; |
64 | |
65 | protected: |
66 | StackFrameHelper() {} |
67 | ~StackFrameHelper() {} |
68 | |
69 | public: |
70 | void SetFrameCount(int iCount) |
71 | { |
72 | iFrameCount = iCount; |
73 | } |
74 | |
75 | int GetFrameCount(void) |
76 | { |
77 | return iFrameCount; |
78 | } |
79 | |
80 | }; |
81 | |
82 | #ifdef USE_CHECKED_OBJECTREFS |
83 | typedef REF <StackFrameHelper> STACKFRAMEHELPERREF; |
84 | #else |
85 | typedef StackFrameHelper* STACKFRAMEHELPERREF; |
86 | #endif |
87 | |
88 | |
89 | class DebugStackTrace |
90 | { |
91 | public: |
92 | |
93 | #ifndef DACCESS_COMPILE |
94 | // the DAC directly uses the GetStackFramesData and DebugStackTraceElement types |
95 | private: |
96 | #endif // DACCESS_COMPILE |
97 | struct DebugStackTraceElement { |
98 | DWORD dwOffset; // native offset |
99 | DWORD dwILOffset; |
100 | MethodDesc *pFunc; |
101 | PCODE ip; |
102 | // TRUE if this element represents the last frame of the foreign |
103 | // exception stack trace. |
104 | BOOL fIsLastFrameFromForeignStackTrace; |
105 | |
106 | // Initialization done under TSL. |
107 | // This is used when first collecting the stack frame data. |
108 | void InitPass1( |
109 | DWORD dwNativeOffset, |
110 | MethodDesc *pFunc, |
111 | PCODE ip |
112 | , BOOL fIsLastFrameFromForeignStackTrace = FALSE |
113 | ); |
114 | |
115 | // Initialization done outside the TSL. |
116 | // This will init the dwILOffset field (and potentially anything else |
117 | // that can't be done under the TSL). |
118 | void InitPass2(); |
119 | }; |
120 | |
121 | public: |
122 | |
123 | struct GetStackFramesData { |
124 | |
125 | // Used for the integer-skip version |
126 | INT32 skip; |
127 | INT32 NumFramesRequested; |
128 | INT32 cElementsAllocated; |
129 | INT32 cElements; |
130 | DebugStackTraceElement* pElements; |
131 | THREADBASEREF TargetThread; |
132 | AppDomain *pDomain; |
133 | BOOL fDoWeHaveAnyFramesFromForeignStackTrace; |
134 | |
135 | |
136 | GetStackFramesData() : skip(0), |
137 | NumFramesRequested (0), |
138 | cElementsAllocated(0), |
139 | cElements(0), |
140 | pElements(NULL), |
141 | TargetThread((THREADBASEREF)(TADDR)NULL) |
142 | { |
143 | LIMITED_METHOD_CONTRACT; |
144 | fDoWeHaveAnyFramesFromForeignStackTrace = FALSE; |
145 | |
146 | } |
147 | |
148 | ~GetStackFramesData() |
149 | { |
150 | delete [] pElements; |
151 | } |
152 | }; |
153 | |
154 | static FCDECL4(void, |
155 | GetStackFramesInternal, |
156 | StackFrameHelper* pStackFrameHelper, |
157 | INT32 iSkip, |
158 | CLR_BOOL fNeedFileInfo, |
159 | Object* pException |
160 | ); |
161 | |
162 | static void GetStackFramesFromException(OBJECTREF * e, GetStackFramesData *pData, PTRARRAYREF * pDynamicMethodArray = NULL); |
163 | |
164 | #ifndef DACCESS_COMPILE |
165 | // the DAC directly calls GetStackFramesFromException |
166 | private: |
167 | #endif |
168 | |
169 | static void GetStackFramesHelper(Frame *pStartFrame, void* pStopStack, GetStackFramesData *pData); |
170 | |
171 | static void GetStackFrames(Frame *pStartFrame, void* pStopStack, GetStackFramesData *pData); |
172 | |
173 | static StackWalkAction GetStackFramesCallback(CrawlFrame* pCf, VOID* data); |
174 | |
175 | }; |
176 | |
177 | #endif // __DEBUG_DEBUGGER_h__ |
178 | |