Add a fourth parameter to the DEFINE_DACVAR macro that is the actual fully qualified...
[platform/upstream/coreclr.git] / src / vm / dbginterface.h
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 //
5 //
6 // COM+99 Debug Interface Header
7 //
8
9
10
11 #ifndef _dbgInterface_h_
12 #define _dbgInterface_h_
13
14 #include "common.h"
15 #include "eedbginterface.h"
16 #include "corjit.h"
17 #include "../debug/inc/dbgipcevents.h"
18 #include "primitives.h"
19
20 typedef DPTR(struct ICorDebugInfo::NativeVarInfo) PTR_NativeVarInfo;
21
22 typedef void (*FAVORCALLBACK)(void *);
23
24 //
25 // The purpose of this object is to serve as an entry point to the
26 // debugger, which used to reside in a seperate DLL.
27 //
28
29 class DebugInterface
30 {
31     VPTR_BASE_VTABLE_CLASS_AND_CTOR(DebugInterface);
32
33 public:
34
35     //
36     // Functions exported from the debugger to the EE.
37     //
38
39 #ifndef DACCESS_COMPILE
40
41     virtual HRESULT Startup(void) = 0;
42
43     virtual HRESULT StartupPhase2(Thread * pThread) = 0;
44
45     // Some callers into the debugger (e.g., ETW rundown) know they will need the lazy
46     // data initialized but cannot afford to have it initialized unpredictably or inside a
47     // lock.  They can use this function to force the data to be initialized at a
48     // controlled point in time
49     virtual void InitializeLazyDataIfNecessary() = 0;
50
51     virtual void SetEEInterface(EEDebugInterface* i) = 0;
52
53     virtual void StopDebugger(void) = 0;
54
55     virtual BOOL IsStopped(void) = 0;
56
57     virtual void ThreadCreated(Thread* pRuntimeThread) = 0;
58
59     virtual void ThreadStarted(Thread* pRuntimeThread) = 0;
60
61     virtual void DetachThread(Thread *pRuntimeThread) = 0;
62
63     // Called when a module is being loaded into an AppDomain.  
64     // This includes when a domain neutral module is loaded into a new AppDomain.
65     // This is called only when a debugger is attached, and will occur after the 
66     // related LoadAssembly and AddAppDomainToIPCBlock calls and before any 
67     // LoadClass calls for this module.
68     virtual void LoadModule(Module *     pRuntimeModule,  // the module being loaded
69                             LPCWSTR      psModuleName,    // module file name
70                             DWORD        dwModuleName,    // number of characters in file name excludign null
71                             Assembly *   pAssembly,       // the assembly the module belongs to
72                             AppDomain *  pAppDomain,      // the AppDomain the module is being loaded into
73                             DomainFile * pDomainFile, 
74                             BOOL         fAttaching) = 0; // true if this notification is due to a debugger 
75                                                           // being attached to the process 
76
77     // Called AFTER LoadModule, and after the module has reached FILE_LOADED. This lets
78     // dbgapi do any processing that needs to wait until the FILE_LOADED stage (e.g.,
79     // binding breakpoints in NGENd generics).
80     virtual void LoadModuleFinished(Module * pModule, AppDomain * pAppDomain) = 0;
81
82     // Called for all modules in an AppDomain when the AppDomain is unloaded.
83     // This includes domain neutral modules that are also loaded into other domains.
84     // This is called only when a debugger is attached, and will occur after all UnloadClass
85     // calls and before any UnloadAssembly or RemoveAppDomainFromIPCBlock calls realted
86     // to this module.  On CLR shutdown, we are not guarenteed to get UnloadModule calls for
87     // all outstanding loaded modules.
88     virtual void UnloadModule(Module* pRuntimeModule, AppDomain *pAppDomain) = 0;
89
90     // Called when a Module* is being destroyed.
91     // Specifically, the Module has completed unloading (which may have been done asyncronously), all resources 
92     // associated are being freed, and the Module* is about to become invalid.  The debugger should remove all
93     // references to this Module*.
94     // NOTE: This is called REGARDLESS of whether a debugger is attached or not, and will occur after any other
95     // notifications about this module (including any RemoveAppDomainFromIPCBlock call indicating the module's
96     // domain has been unloaded).
97     virtual void DestructModule(Module *pModule) = 0;
98
99     virtual BOOL LoadClass(TypeHandle th,
100                            mdTypeDef classMetadataToken,
101                            Module *classModule,
102                            AppDomain *pAppDomain) = 0;
103
104     virtual void UnloadClass(mdTypeDef classMetadataToken,
105                              Module *classModule,
106                              AppDomain *pAppDomain) = 0;
107
108     // Filter we call in 1st-pass to dispatch a CHF callback.
109     // pCatchStackAddress really should be a Frame* onto the stack. That way the CHF stack address
110     // and the debugger's stacktrace Frames will match up.
111     // This is only called by stubs.
112     virtual LONG NotifyOfCHFFilter(EXCEPTION_POINTERS* pExceptionPointers, PVOID pCatchStackAddr) = 0;
113
114
115     virtual bool FirstChanceNativeException(EXCEPTION_RECORD *exception,
116                                        CONTEXT *context,
117                                        DWORD code,
118                                        Thread *thread) = 0;
119
120     // pThread is thread that exception is on.
121     // currentSP is stack frame of the throw site.
122     // currentIP is ip of the throw site.
123     // pStubFrame = NULL if the currentSp is for a non-stub frame (ie, a regular JITed catched).
124     // For stub-based throws, pStubFrame is the EE Frame of the stub.
125     virtual bool FirstChanceManagedException(Thread *pThread, SIZE_T currentIP, SIZE_T currentSP) = 0;
126
127     virtual void FirstChanceManagedExceptionCatcherFound(Thread *pThread,
128                                                          MethodDesc *pMD, TADDR pMethodAddr,
129                                                          BYTE *currentSP,
130                                                          EE_ILEXCEPTION_CLAUSE *pEHClause) = 0;
131
132     virtual LONG LastChanceManagedException(EXCEPTION_POINTERS * pExceptionInfo,
133             Thread *thread,
134             BOOL jitAttachRequested) = 0;
135
136     virtual void ManagedExceptionUnwindBegin(Thread *pThread) = 0;
137
138     virtual void DeleteInterceptContext(void *pContext) = 0;
139
140     virtual void ExceptionFilter(MethodDesc *fd, TADDR pMethodAddr,
141                                  SIZE_T offset,
142                                  BYTE *pStack) = 0;
143
144     virtual void ExceptionHandle(MethodDesc *fd, TADDR pMethodAddr,
145                                  SIZE_T offset,
146                                  BYTE *pStack) = 0;
147
148     virtual void SendUserBreakpoint(Thread *thread) = 0;
149
150     // Send an UpdateModuleSyms event, and block waiting for the debugger to continue it.
151     virtual void SendUpdateModuleSymsEventAndBlock(Module *pRuntimeModule,
152                                           AppDomain *pAppDomain) = 0;
153
154     //
155     // RequestFavor gets the debugger helper thread to call a function. It's
156     // typically called when the current thread can't call the function directly,
157     // e.g, there isn't enough stack space.
158     //
159     // RequestFavor ensures that the helper thread has been initialized to
160     // execute favors and then calls Debugger:DoFavor. It blocks until the
161     // favor callback completes. 
162     //
163     // Parameters:
164     //   fp    - Favour callback function
165     //   pData - the parameter passed to the favor callback function.
166     //
167     // Return values:
168     //   S_OK if the function succeeds, else a failure HRESULT
169     //   
170     virtual HRESULT RequestFavor(FAVORCALLBACK fp, void * pData) = 0;
171
172 #endif // #ifndef DACCESS_COMPILE
173
174     // JITComplete() is called after a method is jit-compiled, successfully or not
175
176 #ifndef DACCESS_COMPILE
177
178     virtual void JITComplete(MethodDesc* fd, TADDR newAddress) = 0;
179
180     //
181     // EnC functions
182     //
183 #ifdef EnC_SUPPORTED
184     // Notify that an existing method has been edited in a loaded type
185     virtual HRESULT UpdateFunction(MethodDesc* md, SIZE_T enCVersion) = 0;
186
187     // Notify that a new method has been added to a loaded type
188     virtual HRESULT AddFunction(MethodDesc* md, SIZE_T enCVersion) = 0;
189
190     virtual HRESULT UpdateNotYetLoadedFunction(mdMethodDef token, Module * pModule, SIZE_T enCVersion) = 0;
191
192     // Notify that a field has been added
193     virtual HRESULT AddField(FieldDesc* fd, SIZE_T enCVersion) = 0;
194
195     // Notify that the EE has completed the remap and is about to resume execution
196     virtual HRESULT RemapComplete(MethodDesc *pMd, TADDR addr, SIZE_T nativeOffset) = 0;
197
198     // Used by the codemanager FixContextForEnC() to update
199     virtual HRESULT MapILInfoToCurrentNative(MethodDesc *pMD,
200                                              SIZE_T ilOffset,
201                                              TADDR nativeFnxStart,
202                                              SIZE_T *nativeOffset) = 0;
203 #endif // EnC_SUPPORTED
204
205     // Get debugger variable information for a specific version of a method
206     virtual     void GetVarInfo(MethodDesc *       fd,         // [IN] method of interest
207                                 void *DebuggerVersionToken,    // [IN] which edit version
208                                 SIZE_T *           cVars,      // [OUT] size of 'vars'
209                                 const ICorDebugInfo::NativeVarInfo **vars     // [OUT] map telling where local vars are stored
210                                 ) = 0;
211
212     virtual void getBoundaries(MethodDesc * ftn,
213                        unsigned int *cILOffsets, DWORD **pILOffsets,
214                        ICorDebugInfo::BoundaryTypes* implictBoundaries) = 0;
215
216     virtual void getVars(MethodDesc * ftn,
217                  ULONG32 *cVars, ICorDebugInfo::ILVarInfo **vars,
218                  bool *extendOthers) = 0;
219
220     virtual BOOL CheckGetPatchedOpcode(CORDB_ADDRESS_TYPE *address, /*OUT*/ PRD_TYPE *pOpcode) = 0;
221
222     virtual PRD_TYPE GetPatchedOpcode(CORDB_ADDRESS_TYPE *ip) = 0;
223
224     virtual void TraceCall(const BYTE *target) = 0;
225
226     virtual bool ThreadsAtUnsafePlaces(void) = 0;
227
228     virtual HRESULT LaunchDebuggerForUser(Thread * pThread, EXCEPTION_POINTERS * pExceptionInfo, BOOL sendManagedEvent, BOOL explicitUserRequest) = 0;
229
230     // Launches a debugger and waits for it to attach
231     virtual void JitAttach(Thread * pThread, EXCEPTION_POINTERS * pExceptionInfo, BOOL willSendManagedEvent, BOOL explicitUserRequest) = 0;
232
233     // Prepares for a jit attach and decides which of several potentially
234     // racing threads get to launch the debugger
235     virtual BOOL PreJitAttach(BOOL willSendManagedEvent, BOOL willLaunchDebugger, BOOL explicitUserRequest) = 0;
236
237     // Waits for a jit attach to complete
238     virtual void WaitForDebuggerAttach() = 0;
239
240     // Completes the jit attach, unblocking all threads waiting for attach,
241     // regardless of whether or not the debugger actually attached
242     virtual void PostJitAttach() = 0;
243
244     virtual void SendUserBreakpointAndSynchronize(Thread * pThread) = 0;
245
246     virtual void SendLogMessage(int iLevel,
247                                 SString * pSwitchName,
248                                 SString * pMessage) = 0;
249
250     // send a custom notification from the target to the RS. This will become an ICorDebugThread and
251     // ICorDebugAppDomain on the RS. 
252     virtual void SendCustomDebuggerNotification(Thread * pThread, DomainFile * pDomainFile, mdTypeDef classToken) = 0;
253
254     // Send an MDA notification. This ultimately translates to an ICorDebugMDA object on the Right-Side.
255     virtual void SendMDANotification(
256         Thread * pThread, // may be NULL. Lets us send on behalf of other threads.
257         SString * szName,
258         SString * szDescription,
259         SString * szXML,
260         CorDebugMDAFlags flags,
261         BOOL bAttach
262     ) = 0;
263
264     virtual bool IsJMCMethod(Module* pModule, mdMethodDef tkMethod) = 0;
265
266     // Given a method, get's its EnC version number. 1 if the method is not EnCed.
267     // Note that MethodDescs are reused between versions so this will give us
268     // the most recent EnC number.
269     virtual int GetMethodEncNumber(MethodDesc * pMethod) = 0;
270
271     virtual void SendLogSwitchSetting (int iLevel,
272                                        int iReason,
273                                        __in_z LPCWSTR pLogSwitchName,
274                                        __in_z LPCWSTR pParentSwitchName) = 0;
275
276     virtual bool IsLoggingEnabled (void) = 0;
277
278     virtual bool GetILOffsetFromNative (MethodDesc *PFD,
279                                                                             const BYTE *pbAddr,
280                                                                             DWORD nativeOffset,
281                                                                             DWORD *ilOffset) = 0;
282
283     virtual HRESULT GetILToNativeMapping(MethodDesc *pMD,
284                                          ULONG32 cMap,
285                                          ULONG32 *pcMap,
286                                          COR_DEBUG_IL_TO_NATIVE_MAP map[]) = 0;
287
288     virtual HRESULT GetILToNativeMappingIntoArrays(
289         MethodDesc * pMD, 
290         USHORT cMapMax, 
291         USHORT * pcMap,
292         UINT ** prguiILOffset, 
293         UINT ** prguiNativeOffset) = 0;
294     
295     virtual DWORD GetHelperThreadID(void ) = 0;
296
297     // Called whenever a new AppDomain is created, regardless of whether a debugger is attached.
298     // This will be called before any LoadAssembly calls for assemblies in this domain.
299     virtual HRESULT AddAppDomainToIPC (AppDomain *pAppDomain) = 0;
300
301     // Called whenever an AppDomain is unloaded, regardless of whether a Debugger is attached
302     // This will occur after any UnloadAssembly and UnloadModule callbacks for this domain (if any).
303     virtual HRESULT RemoveAppDomainFromIPC (AppDomain *pAppDomain) = 0;
304
305     virtual HRESULT UpdateAppDomainEntryInIPC (AppDomain *pAppDomain) = 0;
306
307     // Called when an assembly is being loaded into an AppDomain.  
308     // This includes when a domain neutral assembly is loaded into a new AppDomain.
309     // This is called only when a debugger is attached, and will occur after the 
310     // related AddAppDomainToIPCBlock call and before any LoadModule or
311     // LoadClass calls for this assembly.
312     virtual void LoadAssembly(DomainAssembly * pDomainAssembly) = 0; // the assembly being loaded
313
314
315     // Called for all assemblies in an AppDomain when the AppDomain is unloaded.
316     // This includes domain neutral assemblies that are also loaded into other domains.
317     // This is called only when a debugger is attached, and will occur after all UnloadClass
318     // and UnloadModule calls and before any RemoveAppDomainFromIPCBlock calls realted
319     // to this assembly.  On CLR shutdown, we are not guarenteed to get UnloadAssembly calls for
320     // all outstanding loaded assemblies.
321     virtual void UnloadAssembly(DomainAssembly * pDomainAssembly) = 0;
322
323     virtual HRESULT SetILInstrumentedCodeMap(MethodDesc *fd,
324                                              BOOL fStartJit,
325                                              ULONG32 cILMapEntries,
326                                              COR_IL_MAP rgILMapEntries[]) = 0;
327
328     virtual void EarlyHelperThreadDeath(void) = 0;
329
330     virtual void ShutdownBegun(void) = 0;
331
332     virtual void LockDebuggerForShutdown(void) = 0;
333
334     virtual void DisableDebugger(void) = 0;
335
336     virtual HRESULT NameChangeEvent(AppDomain *pAppDomain,
337                                     Thread *pThread) = 0;
338
339     // send an event to the RS indicating that there's a Ctrl-C or Ctrl-Break
340     virtual BOOL SendCtrlCToDebugger(DWORD dwCtrlType) = 0;
341
342     // Allows the debugger to keep an up to date list of special threads
343     virtual HRESULT UpdateSpecialThreadList(DWORD cThreadArrayLength,
344                                             DWORD *rgdwThreadIDArray) = 0;
345
346     // Updates the pointer for the debugger services
347     virtual void SetIDbgThreadControl(IDebuggerThreadControl *pIDbgThreadControl) = 0;
348
349     virtual DWORD GetRCThreadId(void) = 0;
350
351     virtual HRESULT GetVariablesFromOffset(MethodDesc                 *pMD,
352                                            UINT                        varNativeInfoCount,
353                                            ICorDebugInfo::NativeVarInfo *varNativeInfo,
354                                            SIZE_T                      offsetFrom,
355                                            CONTEXT                    *pCtx,
356                                            SIZE_T                     *rgVal1,
357                                            SIZE_T                     *rgVal2,
358                                            UINT                       uRgValSize,
359                                            BYTE                     ***rgpVCs) = 0;
360
361     virtual HRESULT SetVariablesAtOffset(MethodDesc                 *pMD,
362                                          UINT                        varNativeInfoCount,
363                                          ICorDebugInfo::NativeVarInfo *varNativeInfo,
364                                          SIZE_T                      offsetTo,
365                                          CONTEXT                    *pCtx,
366                                          SIZE_T                     *rgVal1,
367                                          SIZE_T                     *rgVal2,
368                                          BYTE                      **rgpVCs) = 0;
369
370     virtual BOOL IsThreadContextInvalid(Thread *pThread) = 0;
371
372     // For Just-My-Code (aka Just-User-Code).
373     // The jit inserts probes that look like.
374     // if (*pAddr != 0) call g_pDebugInterface->OnMethodEnter()
375
376     // Invoked when we enter a user method.
377     // pIP is an ip within the method, right after the prolog.
378     virtual void OnMethodEnter(void * pIP) = 0;
379
380     // Given a method, the debugger provides the address of the flag.
381     // This allows the debugger to store the flag whereever it wants
382     // and with whatever granularity (per-module, per-class, per-function, etc).
383     virtual DWORD* GetJMCFlagAddr(Module * pModule) = 0;
384
385     // notification for SQL fiber debugging support
386     virtual void CreateConnection(CONNID dwConnectionId, __in_z WCHAR *wzName) = 0;
387     virtual void DestroyConnection(CONNID dwConnectionId) = 0;
388     virtual void ChangeConnection(CONNID dwConnectionId) = 0;
389
390     //
391     // This function is used to identify the helper thread.
392     //
393     virtual bool ThisIsHelperThread(void) = 0;
394
395     virtual HRESULT ReDaclEvents(PSECURITY_DESCRIPTOR securityDescriptor) = 0;
396
397     virtual BOOL ShouldAutoAttach() = 0;
398     virtual BOOL FallbackJITAttachPrompt() = 0;
399     virtual HRESULT SetFiberMode(bool isFiberMode) = 0;
400
401 #ifdef FEATURE_INTEROP_DEBUGGING
402     virtual LONG FirstChanceSuspendHijackWorker(PCONTEXT pContext, PEXCEPTION_RECORD pExceptionRecord) = 0;
403 #endif
404
405 #endif // #ifndef DACCESS_COMPILE
406
407 #ifdef DACCESS_COMPILE
408     virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags) = 0;
409     virtual void EnumMemoryRegionsIfFuncEvalFrame(CLRDataEnumMemoryFlags flags, Frame * pFrame) = 0;
410 #endif
411 };
412
413 #ifndef DACCESS_COMPILE
414 // Helper to make GCC compile. GCC can't handle putting a virtual call in a filter.
415 struct NotifyOfCHFFilterWrapperParam { void *pFrame; };
416 LONG NotifyOfCHFFilterWrapper(EXCEPTION_POINTERS *pExceptionInfo, PVOID pNotifyOfCHFFilterWrapperParam);
417 #endif
418
419
420 #endif // _dbgInterface_h_