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#ifndef _MDA_ASSISTANTS_
7#define _MDA_ASSISTANTS_
8
9#include "common.h"
10#include "mda.h"
11#include "mlinfo.h"
12#include <dbginterface.h>
13
14/*
15
16//-----------------------------------------------------------------------------
17// How to add a new MDA:
18//-----------------------------------------------------------------------------
19
201) add a new class that derives from MdaAssistant to src\vm\mdaAssistants.h
21- the new class should have some function to report the error (we'll call it ReportXYZ()).
22The function is not virtual, and so can take any needed parameters and will be called explicitly wherever you want to fire the MDA.
23
242) Add the new implementation to src\vm\mdaAssistants.cpp
25See the other report functions for an example (eg, MdaLoaderLock::ReportViolation)
26
273) The MDA contains a user-description string. This must be localized, and so it comes from a resource file.
28 - add a new resource ID to src\dlls\mscorrc\Resource.h (eg, MDARC_REPORT_AV_ON_COM_RELEASE)
29
304) add the actual text to src\dlls\mscorrc\Mscorrc.rc.
31 - add a #define MDARC_XYZ_MSG string. This is a printf format string and may contain parameters.
32 - add an entry into the MDARC stringtable like "MDARC_XYZ_MSG MDAARC_XYZ"
33
345) In order to get an instance of the MDA:
35 Use a construct like:
36 MdaFatalExecutionEngineError * pMDA = MDA_GET_ASSISTANT(FatalExecutionEngineError);
37
38 The macro parameter is the MDA class name minus the "MDA" prefix.
39 This may return null if the MDA is not available.
40
416) Update mdaAssistantSchemas.inl
42
437) Add it to any appropriate groups in mdaGroups.inl. Please be sure to follow each groups policy.
44
458) Write a test for it.
46*/
47
48#ifdef MDA_SUPPORTED
49
50// Until Mda offers first class support for managed code we'll just make targetd ecalls.
51class MdaManagedSupport
52{
53public:
54 static FCDECL0(void, MemberInfoCacheCreation);
55 static FCDECL0(void, DateTimeInvalidLocalFormat);
56 static FCDECL1(void, ReportStreamWriterBufferedDataLost, StringObject * pString);
57 static FCDECL0(FC_BOOL_RET, IsStreamWriterBufferedDataLostEnabled);
58 static FCDECL0(FC_BOOL_RET, IsStreamWriterBufferedDataLostCaptureAllocatedCallStack);
59 static FCDECL0(FC_BOOL_RET, IsInvalidGCHandleCookieProbeEnabled);
60 static FCDECL1(void, FireInvalidGCHandleCookieProbe, LPVOID cookie);
61 static FCDECL1(void, ReportErrorSafeHandleRelease, ExceptionObject * pException);
62};
63
64// MDA classes do not derive from MdaAssistant in the type system, but, rather, use this macro to
65// ensure that their layout is identical to what it would be had they derived from MdaAssistant.
66// This allows them to be "aggregates", which C++ will allow to be initialized at compile time.
67// This means that we must explicitly coerce from a derived type to the "base" type as needed.
68//
69// Note that the layout is asserted to be correct at compile time via the MDA_DEFINE_ASSISTANT
70// macro.
71#define MDA_ASSISTANT_BASE_MEMBERS \
72 MdaAssistant* AsMdaAssistant() \
73 { \
74 LIMITED_METHOD_CONTRACT; \
75 return (MdaAssistant*)this; \
76 } \
77 void Enable() \
78 { \
79 LIMITED_METHOD_CONTRACT; \
80 ManagedDebuggingAssistants::Enable( \
81 m_assistantDeclDef, this->AsMdaAssistant()); \
82 } \
83 MdaElemDeclDef m_assistantDeclDef; \
84 MdaElemDeclDef m_assistantMsgDeclDef; \
85 bool m_bSuppressDialog \
86
87
88//
89// MdaFramework
90//
91class MdaFramework
92{
93public:
94 void Initialize(MdaXmlElement* pXmlInput);
95 void DumpDiagnostics();
96
97 MDA_ASSISTANT_BASE_MEMBERS;
98 BOOL m_disableAsserts;
99 BOOL m_dumpSchemaSchema;
100 BOOL m_dumpAssistantSchema;
101 BOOL m_dumpAssistantMsgSchema;
102 BOOL m_dumpMachineConfig;
103 BOOL m_dumpAppConfig;
104};
105
106
107//
108// MdaJitCompilationStart
109//
110class MdaJitCompilationStart
111{
112public:
113 void Initialize(MdaXmlElement* pXmlInput);
114 void NowCompiling(MethodDesc* pMethodDesc);
115
116 MDA_ASSISTANT_BASE_MEMBERS;
117 MdaQuery::CompiledQueries* m_pMethodFilter;
118 BOOL m_bBreak;
119};
120
121
122//
123// MdaLoadFromContext
124//
125class MdaLoadFromContext
126{
127public:
128 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
129 void NowLoading(IAssembly** ppIAssembly, StackCrawlMark *pCallerStackMark);
130
131 MDA_ASSISTANT_BASE_MEMBERS;
132};
133
134
135// MdaBindingFailure
136//
137class MdaBindingFailure
138{
139public:
140 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
141 void BindFailed(AssemblySpec *pSpec, OBJECTREF *pExceptionObj);
142
143 MDA_ASSISTANT_BASE_MEMBERS;
144};
145
146
147//
148// MdaReflection
149//
150class MdaMemberInfoCacheCreation
151{
152public:
153 void Initialize(MdaXmlElement* pXmlInput) { WRAPPER_NO_CONTRACT; }
154 void MemberInfoCacheCreation();
155
156 MDA_ASSISTANT_BASE_MEMBERS;
157};
158
159
160//
161// MdaPInvokeLog
162//
163class MdaPInvokeLog
164{
165public:
166 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; m_pXmlInput = pXmlInput; }
167 BOOL Filter(SString& sszDllName);
168 void LogPInvoke(NDirectMethodDesc* pMd, HINSTANCE hMod);
169
170 MDA_ASSISTANT_BASE_MEMBERS;
171 MdaXmlElement* m_pXmlInput;
172};
173
174
175//
176// MdaOverlappedFreeError
177//
178class MdaOverlappedFreeError
179{
180public:
181 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
182 void ReportError(LPVOID pOverlapped);
183
184 MDA_ASSISTANT_BASE_MEMBERS;
185};
186
187//
188// MdaInvalidOverlappedToPinvoke
189//
190class MdaInvalidOverlappedToPinvoke
191{
192public:
193 void Initialize(MdaXmlElement* pXmlInput);
194
195 BOOL ShouldHook(MethodDesc *pMD);
196
197 // Called when setting up the pinvoke target
198 LPVOID Register(HINSTANCE hmod,LPVOID pvTarget);
199
200 // Logs the MDA error if the overlapped pointer isn't in the gc heap
201 LPVOID CheckOverlappedPointer(UINT index,LPVOID pOverlapped);
202
203 struct pinvoke_entry
204 {
205 LPCWSTR m_moduleName;
206 LPCWSTR m_functionName;
207 LPVOID m_mdaFunction;
208 LPVOID m_realFunction;
209 HINSTANCE m_hmod;
210
211 void Init(LPCWSTR moduleName, LPCWSTR functionName, LPVOID mdaFunction)
212 {
213 WRAPPER_NO_CONTRACT;
214 m_moduleName = moduleName;
215 m_functionName = functionName;
216 m_mdaFunction = mdaFunction;
217 m_realFunction = NULL;
218 m_hmod = NULL;
219 }
220 };
221 BOOL InitializeModuleFunctions(HINSTANCE hmod);
222
223 MDA_ASSISTANT_BASE_MEMBERS;
224 pinvoke_entry *m_entries;
225 UINT m_entryCount;
226 BOOL m_bJustMyCode;
227};
228
229#ifdef _TARGET_X86_
230//
231// PInvokeStackImbalance
232//
233struct StackImbalanceCookie
234{
235 enum
236 {
237 // combined with the unmanaged calling convention (code:pmCallConvMask) in
238 // code:m_callConv if the unmanaged target has a floating point return value
239 HAS_FP_RETURN_VALUE = 0x80000000
240 };
241
242 // Filled in by stub generated by code:NDirectMethodDesc.GenerateStubForMDA or
243 // code:COMDelegate::GenerateStubForMDA:
244 MethodDesc *m_pMD; // dispatching MD (P/Invoke or delegate's Invoke)
245 LPVOID m_pTarget; // target address
246 DWORD m_dwStackArgSize; // number of arg bytes pushed on stack
247 DWORD m_callConv; // unmanaged calling convention, highest bit indicates FP return
248
249 // Pre-call ESP as recorded by PInvokeStackImbalanceHelper:
250 DWORD m_dwSavedEsp;
251};
252
253class MdaPInvokeStackImbalance
254{
255public:
256 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
257 void CheckStack(StackImbalanceCookie *pSICookie, DWORD dwPostESP);
258
259 MDA_ASSISTANT_BASE_MEMBERS;
260};
261#endif
262
263
264//
265// DllMainReturnsFalse
266//
267class MdaDllMainReturnsFalse
268{
269public:
270 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
271 void ReportError();
272
273 MDA_ASSISTANT_BASE_MEMBERS;
274};
275
276
277
278//
279// MdaModuloObjectHashcode
280//
281class MdaModuloObjectHashcode
282{
283public:
284 void Initialize(MdaXmlElement* pXmlInput)
285 {
286 CONTRACTL
287 {
288 THROWS;
289 GC_NOTRIGGER;
290 MODE_ANY;
291 }
292 CONTRACTL_END;
293
294 m_modulus = pXmlInput->GetAttribute(MdaAttrDecl(Modulus))->GetValueAsInt32();
295 if (m_modulus <= 0)
296 m_modulus = 1;
297 }
298
299 INT32 GetModulo() { LIMITED_METHOD_CONTRACT; _ASSERTE(m_modulus > 0); return m_modulus; }
300
301 MDA_ASSISTANT_BASE_MEMBERS;
302 INT32 m_modulus;
303};
304
305
306//
307// MdaGCUnmanagedToManaged
308//
309class MdaGcUnmanagedToManaged
310{
311public:
312 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
313 void TriggerGC(); // calls to GC.Collect & GC.WaitForPendingFinalizers are also generated to IL stubs
314
315 MDA_ASSISTANT_BASE_MEMBERS;
316};
317
318
319//
320// MdaGCManagedToUnmanaged
321//
322class MdaGcManagedToUnmanaged
323{
324public:
325 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
326 void TriggerGC(); // calls to GC.Collect & GC.WaitForPendingFinalizers are also generated to IL stubs
327
328 MDA_ASSISTANT_BASE_MEMBERS;
329};
330
331
332//
333// MdaLoaderLock
334//
335class MdaLoaderLock
336{
337public:
338 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
339 void ReportViolation(HINSTANCE hInst);
340
341 MDA_ASSISTANT_BASE_MEMBERS;
342};
343
344
345//
346// MdaReentrancy
347//
348class MdaReentrancy
349{
350public:
351 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
352 void ReportViolation();
353
354 MDA_ASSISTANT_BASE_MEMBERS;
355};
356
357
358//
359// MdaAsynchronousThreadAbort
360//
361class MdaAsynchronousThreadAbort
362{
363public:
364 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
365 void ReportViolation(Thread *pCallingThread, Thread *pAbortedThread);
366
367 MDA_ASSISTANT_BASE_MEMBERS;
368};
369
370
371//
372// MdaAsynchronousThreadAbort
373//
374class MdaDangerousThreadingAPI
375{
376public:
377 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
378 void ReportViolation(__in_z WCHAR *apiName);
379
380 MDA_ASSISTANT_BASE_MEMBERS;
381};
382
383
384//
385// MdaReportAvOnComRelease
386//
387class MdaReportAvOnComRelease
388{
389public:
390 void Initialize(MdaXmlElement* pXmlInput)
391 {
392 CONTRACTL
393 {
394 THROWS;
395 GC_NOTRIGGER;
396 MODE_ANY;
397 }
398 CONTRACTL_END;
399 m_allowAv = pXmlInput->GetAttribute(MdaAttrDecl(AllowAv))->GetValueAsBool();
400 }
401
402 void ReportHandledException(RCW* pRCW);
403
404 BOOL AllowAV() { LIMITED_METHOD_CONTRACT; return m_allowAv; }
405
406 MDA_ASSISTANT_BASE_MEMBERS;
407 BOOL m_allowAv;
408};
409
410
411
412//
413// MdaFatalExecutionEngineError
414//
415class MdaFatalExecutionEngineError
416{
417public:
418 void Initialize(MdaXmlElement* pXmlInput)
419 {
420 WRAPPER_NO_CONTRACT;
421 }
422
423 // Report a FatalExecutionEngine error.
424 // It is assumed to be on the current thread.
425 void ReportFEEE(TADDR addrOfError, HRESULT hrError);
426
427 MDA_ASSISTANT_BASE_MEMBERS;
428};
429
430//
431// MdaCallbackOnCollectedDelegate
432//
433class MdaCallbackOnCollectedDelegate
434{
435public:
436 void Initialize(MdaXmlElement* pXmlInput)
437 {
438 CONTRACTL
439 {
440 THROWS;
441 GC_NOTRIGGER;
442 MODE_ANY;
443 }
444 CONTRACTL_END;
445
446 m_size = pXmlInput->GetAttribute(MdaAttrDecl(ListSize))->GetValueAsInt32();
447 if (m_size < 50)
448 m_size = 1000;
449
450 if (m_size > 2000)
451 m_size = 1000;
452
453 m_pList = new UMEntryThunk*[m_size];
454 memset(m_pList, 0, sizeof(UMEntryThunk*) * m_size);
455 }
456
457 void ReportViolation(MethodDesc* pMD);
458 void AddToList(UMEntryThunk* pEntryThunk);
459
460private:
461 void ReplaceEntry(int index, UMEntryThunk* pET);
462
463public:
464 MDA_ASSISTANT_BASE_MEMBERS;
465 UMEntryThunk** m_pList;
466 int m_iIndex;
467 int m_size;
468};
469
470//
471// InvalidMemberDeclaration
472//
473class MdaInvalidMemberDeclaration
474{
475public:
476 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
477
478#ifdef FEATURE_COMINTEROP
479 void ReportViolation(ComCallMethodDesc *pCMD, OBJECTREF *pExceptionObj);
480#endif //FEATURE_COMINTEROP
481
482 MDA_ASSISTANT_BASE_MEMBERS;
483};
484
485
486//
487// MdaExceptionSwallowedOnCallFromCom
488//
489class MdaExceptionSwallowedOnCallFromCom
490{
491public:
492 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
493 void ReportViolation(MethodDesc *pMD, OBJECTREF *pExceptionObj);
494
495 MDA_ASSISTANT_BASE_MEMBERS;
496};
497
498
499//
500// MdaInvalidVariant
501//
502class MdaInvalidVariant
503{
504public:
505 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
506 void ReportViolation();
507
508 MDA_ASSISTANT_BASE_MEMBERS;
509};
510
511
512//
513// MdaInvalidApartmentStateChange
514//
515class MdaInvalidApartmentStateChange
516{
517public:
518 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
519 void ReportViolation(Thread* pThread, Thread::ApartmentState state, BOOL fAlreadySet);
520
521 MDA_ASSISTANT_BASE_MEMBERS;
522};
523
524
525
526//
527// MdaFailedQI
528//
529HRESULT MdaFailedQIAssistantCallback(LPVOID pData);
530
531typedef struct
532{
533 RCW* pWrapper;
534 IID iid;
535 BOOL fSuccess;
536} MdaFailedQIAssistantCallbackData;
537
538#define OLE32DLL W("ole32.dll")
539
540class MdaFailedQI
541{
542public:
543 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
544 void ReportAdditionalInfo(HRESULT hr, RCW* pRCW, GUID iid, MethodTable* pMT);
545
546 MDA_ASSISTANT_BASE_MEMBERS;
547};
548
549
550//
551// MdaDisconnectedContext
552//
553class MdaDisconnectedContext
554{
555public:
556 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
557 void ReportViolationDisconnected(LPVOID context, HRESULT hr);
558 void ReportViolationCleanup(LPVOID context1, LPVOID context2, HRESULT hr);
559
560 MDA_ASSISTANT_BASE_MEMBERS;
561};
562
563
564//
565// MdaNotMarshalable
566//
567class MdaNotMarshalable
568{
569public:
570 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
571 void ReportViolation();
572
573 MDA_ASSISTANT_BASE_MEMBERS;
574};
575
576
577
578//
579// MdaMarshalCleanupError
580//
581class MdaMarshalCleanupError
582{
583public:
584 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
585 void ReportErrorThreadCulture(OBJECTREF *pExceptionObj);
586 void ReportErrorSafeHandleRelease(OBJECTREF *pExceptionObj);
587 void ReportErrorSafeHandleProp(OBJECTREF *pExceptionObj);
588 void ReportErrorCustomMarshalerCleanup(TypeHandle typeCustomMarshaler, OBJECTREF *pExceptionObj);
589
590 MDA_ASSISTANT_BASE_MEMBERS;
591};
592
593
594//
595// MdaInvalidIUnknown
596//
597class MdaInvalidIUnknown
598{
599public:
600 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
601 void ReportViolation();
602
603 MDA_ASSISTANT_BASE_MEMBERS;
604};
605
606
607//
608// MdaContextSwitchDeadlock
609//
610class MdaContextSwitchDeadlock
611{
612public:
613 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
614 void ReportDeadlock(LPVOID Origin, LPVOID Destination);
615
616 MDA_ASSISTANT_BASE_MEMBERS;
617};
618
619
620//
621// MdaRaceOnRCWCleanup
622//
623class MdaRaceOnRCWCleanup
624{
625public:
626 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
627 void ReportViolation();
628
629 MDA_ASSISTANT_BASE_MEMBERS;
630};
631
632//
633// MdaMarshaling
634//
635class MdaMarshaling
636{
637public:
638 void Initialize(MdaXmlElement* pXmlInput);
639 void ReportFieldMarshal(FieldMarshaler* pFM);
640
641private:
642 void GetManagedSideForMethod(SString& strManagedMarshalType, Module* pModule, SigPointer sig, CorElementType elemType);
643 void GetUnmanagedSideForMethod(SString& strNativeMarshalType, MarshalInfo* mi, BOOL fSizeIsSpecified);
644 void GetManagedSideForField(SString& strManagedMarshalType, FieldDesc* pFD);
645 void GetUnmanagedSideForField(SString& strUnmanagedMarshalType, FieldMarshaler* pFM);
646 BOOL CheckForPrimitiveType(CorElementType elemType, SString& strPrimitiveType);
647
648public:
649 MDA_ASSISTANT_BASE_MEMBERS;
650 MdaQuery::CompiledQueries* m_pMethodFilter;
651 MdaQuery::CompiledQueries* m_pFieldFilter;
652};
653
654
655
656//
657// InvalidFunctionPointerInDelegate
658//
659class MdaInvalidFunctionPointerInDelegate
660{
661public:
662 void Initialize(MdaXmlElement* pXmlInput) {LIMITED_METHOD_CONTRACT; }
663 void ReportViolation(LPVOID pFunc);
664
665 MDA_ASSISTANT_BASE_MEMBERS;
666};
667
668
669//
670// DirtyCastAndCallOnInterface
671//
672class MdaDirtyCastAndCallOnInterface
673{
674public:
675 void Initialize(MdaXmlElement* pXmlInput) {LIMITED_METHOD_CONTRACT; }
676 void ReportViolation(IUnknown* pUnk);
677
678 MDA_ASSISTANT_BASE_MEMBERS;
679};
680
681
682//
683// InvalidCERCall
684//
685class MdaInvalidCERCall
686{
687public:
688 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
689 void ReportViolation(MethodDesc* pCallerMD, MethodDesc *pCalleeMD, DWORD dwOffset);
690
691 MDA_ASSISTANT_BASE_MEMBERS;
692};
693
694
695
696//
697// VirtualCERCall
698//
699class MdaVirtualCERCall
700{
701public:
702 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
703 void ReportViolation(MethodDesc* pCallerMD, MethodDesc *pCalleeMD, DWORD dwOffset);
704
705 MDA_ASSISTANT_BASE_MEMBERS;
706};
707
708
709
710//
711// OpenGenericCERCall
712//
713class MdaOpenGenericCERCall
714{
715public:
716 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
717 void ReportViolation(MethodDesc* pMD);
718
719 MDA_ASSISTANT_BASE_MEMBERS;
720};
721
722
723
724//
725// IllegalPrepareConstrainedRegion
726//
727class MdaIllegalPrepareConstrainedRegion
728{
729public:
730 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
731 void ReportViolation(MethodDesc* pMD, DWORD dwOffset);
732
733 MDA_ASSISTANT_BASE_MEMBERS;
734};
735
736
737
738//
739// ReleaseHandleFailed
740//
741class MdaReleaseHandleFailed
742{
743public:
744 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
745 void ReportViolation(TypeHandle th, LPVOID lpvHandle);
746
747 MDA_ASSISTANT_BASE_MEMBERS;
748};
749
750
751//
752// NonComVisibleBaseClass
753//
754class MdaNonComVisibleBaseClass
755{
756public:
757 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
758#ifdef FEATURE_COMINTEROP
759 void ReportViolation(MethodTable *pMT, BOOL fForIDispatch);
760#endif //FEATURE_COMINTEROP
761
762 MDA_ASSISTANT_BASE_MEMBERS;
763};
764
765
766//
767// InvalidGCHandleCookie
768//
769class MdaInvalidGCHandleCookie
770{
771public:
772 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
773 void ReportError(LPVOID cookie);
774
775 MDA_ASSISTANT_BASE_MEMBERS;
776};
777
778//
779// MdaXmlValidator
780//
781class MdaXmlValidator
782{
783public:
784 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
785
786 MDA_ASSISTANT_BASE_MEMBERS;
787};
788
789
790#ifdef _DEBUG
791//
792// MdaXmlValidationError
793//
794class MdaXmlValidationError
795{
796public:
797 void Initialize(MdaXmlElement* pXml) { LIMITED_METHOD_CONTRACT; }
798
799public:
800 void ReportError(MdaSchema::ValidationResult* pValidationResult);
801
802 MDA_ASSISTANT_BASE_MEMBERS;
803};
804#endif
805
806
807//
808// MdaInvalidConfigFile
809//
810class MdaInvalidConfigFile
811{
812public:
813 void Initialize(MdaXmlElement* pXml) { LIMITED_METHOD_CONTRACT; }
814
815public:
816 void ReportError(MdaElemDeclDef configFile);
817
818 MDA_ASSISTANT_BASE_MEMBERS;
819};
820
821//
822// MdaDateTimeInvalidLocalFormat
823//
824class MdaDateTimeInvalidLocalFormat
825{
826public:
827 void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; }
828 void ReportError();
829
830 MDA_ASSISTANT_BASE_MEMBERS;
831};
832
833//
834// MdaStreamWriterBufferedDataLost
835//
836class MdaStreamWriterBufferedDataLost
837{
838public:
839 void Initialize(MdaXmlElement* pXmlInput)
840 {
841 CONTRACTL
842 {
843 THROWS;
844 GC_NOTRIGGER;
845 MODE_ANY;
846 }
847 CONTRACTL_END;
848 m_captureAllocatedCallStack = pXmlInput->GetAttribute(MdaAttrDecl(CaptureAllocatedCallStack))->GetValueAsBool();
849 }
850
851 BOOL CaptureAllocatedCallStack() { LIMITED_METHOD_CONTRACT; return m_captureAllocatedCallStack; }
852
853 void ReportError(SString text);
854
855 MDA_ASSISTANT_BASE_MEMBERS;
856 BOOL m_captureAllocatedCallStack;
857};
858
859class ValidateMdaAssistantLayout
860{
861 static_assert_no_msg(sizeof(MdaAssistant) == 3);
862#define MDA_VALIDATE_MEMBER_LAYOUT
863#include "mdaschema.inl"
864#undef MDA_VALIDATE_MEMBER_LAYOUT
865};
866
867//
868// MdaStaticHeap
869//
870
871typedef struct
872{
873 // This array is always live. Checking whether an assistant is enabled is
874 // simply a fetch from this array.
875 MdaAssistant* m_assistants[MdaElemDef(AssistantMax)];
876
877 // This pointer will point to the m_mda memory region, where the actual
878 // ManagedDebuggingAssistants instance lives. It may be null if we no MDAs
879 // were enabled.
880 ManagedDebuggingAssistants* m_pMda;
881 BYTE m_mda[sizeof(ManagedDebuggingAssistants)];
882
883#define MDA_ASSISTANT_HEAP_RAW
884#include "mdaschema.inl"
885#undef MDA_ASSISTANT_HEAP_RAW
886
887 void DisableAll()
888 {
889 LIMITED_METHOD_CONTRACT;
890 memset(&m_assistants, 0, sizeof(m_assistants));
891 }
892}
893MdaStaticHeap;
894typedef DPTR(MdaStaticHeap) PTR_MdaStaticHeap;
895extern MdaStaticHeap g_mdaStaticHeap;
896
897
898// static
899FORCEINLINE void ManagedDebuggingAssistants::Enable(MdaElemDeclDef assistantDeclDef, MdaAssistant* pMda)
900{
901 g_mdaStaticHeap.m_assistants[assistantDeclDef] = pMda;
902}
903
904#ifndef DACCESS_COMPILE
905FORCEINLINE MdaAssistant* ManagedDebuggingAssistants::GetAssistant(MdaElemDeclDef id)
906{
907 WRAPPER_NO_CONTRACT;
908
909 // If this assert fires, you should consider using GET_ASSISTANT_EX / TRIGGER_ASSISTANT_EX
910 _ASSERTE((g_pDebugInterface == NULL) || !g_pDebugInterface->ThisIsHelperThread());
911
912 return g_mdaStaticHeap.m_assistants[id];
913}
914
915FORCEINLINE MdaAssistant* ManagedDebuggingAssistants::GetAssistantEx(MdaElemDeclDef id)
916{
917 WRAPPER_NO_CONTRACT;
918
919 MdaAssistant* pMda = g_mdaStaticHeap.m_assistants[id];
920 if ((pMda != NULL) && ((g_pDebugInterface == NULL) || !g_pDebugInterface->ThisIsHelperThread()))
921 return pMda;
922
923 return NULL;
924}
925#endif // DACCESS_COMPILE
926
927void TriggerGCForMDAInternal();
928
929#endif // MDA_SUPPORTED
930#endif // _MDA_ASSISTANTS_
931
932
933