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 | |
20 | 1) 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()). |
22 | The function is not virtual, and so can take any needed parameters and will be called explicitly wherever you want to fire the MDA. |
23 | |
24 | 2) Add the new implementation to src\vm\mdaAssistants.cpp |
25 | See the other report functions for an example (eg, MdaLoaderLock::ReportViolation) |
26 | |
27 | 3) 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 | |
30 | 4) 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 | |
34 | 5) 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 | |
41 | 6) Update mdaAssistantSchemas.inl |
42 | |
43 | 7) Add it to any appropriate groups in mdaGroups.inl. Please be sure to follow each groups policy. |
44 | |
45 | 8) 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. |
51 | class MdaManagedSupport |
52 | { |
53 | public: |
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 | // |
91 | class MdaFramework |
92 | { |
93 | public: |
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 | // |
110 | class MdaJitCompilationStart |
111 | { |
112 | public: |
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 | // |
125 | class MdaLoadFromContext |
126 | { |
127 | public: |
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 | // |
137 | class MdaBindingFailure |
138 | { |
139 | public: |
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 | // |
150 | class MdaMemberInfoCacheCreation |
151 | { |
152 | public: |
153 | void Initialize(MdaXmlElement* pXmlInput) { WRAPPER_NO_CONTRACT; } |
154 | void MemberInfoCacheCreation(); |
155 | |
156 | MDA_ASSISTANT_BASE_MEMBERS; |
157 | }; |
158 | |
159 | |
160 | // |
161 | // MdaPInvokeLog |
162 | // |
163 | class MdaPInvokeLog |
164 | { |
165 | public: |
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 | // |
178 | class MdaOverlappedFreeError |
179 | { |
180 | public: |
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 | // |
190 | class MdaInvalidOverlappedToPinvoke |
191 | { |
192 | public: |
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 | // |
233 | struct 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 | |
253 | class MdaPInvokeStackImbalance |
254 | { |
255 | public: |
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 | // |
267 | class MdaDllMainReturnsFalse |
268 | { |
269 | public: |
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 | // |
281 | class MdaModuloObjectHashcode |
282 | { |
283 | public: |
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 | // |
309 | class MdaGcUnmanagedToManaged |
310 | { |
311 | public: |
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 | // |
322 | class MdaGcManagedToUnmanaged |
323 | { |
324 | public: |
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 | // |
335 | class MdaLoaderLock |
336 | { |
337 | public: |
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 | // |
348 | class MdaReentrancy |
349 | { |
350 | public: |
351 | void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; } |
352 | void ReportViolation(); |
353 | |
354 | MDA_ASSISTANT_BASE_MEMBERS; |
355 | }; |
356 | |
357 | |
358 | // |
359 | // MdaAsynchronousThreadAbort |
360 | // |
361 | class MdaAsynchronousThreadAbort |
362 | { |
363 | public: |
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 | // |
374 | class MdaDangerousThreadingAPI |
375 | { |
376 | public: |
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 | // |
387 | class MdaReportAvOnComRelease |
388 | { |
389 | public: |
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 | // |
415 | class MdaFatalExecutionEngineError |
416 | { |
417 | public: |
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 | // |
433 | class MdaCallbackOnCollectedDelegate |
434 | { |
435 | public: |
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 | |
460 | private: |
461 | void ReplaceEntry(int index, UMEntryThunk* pET); |
462 | |
463 | public: |
464 | MDA_ASSISTANT_BASE_MEMBERS; |
465 | UMEntryThunk** m_pList; |
466 | int m_iIndex; |
467 | int m_size; |
468 | }; |
469 | |
470 | // |
471 | // InvalidMemberDeclaration |
472 | // |
473 | class MdaInvalidMemberDeclaration |
474 | { |
475 | public: |
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 | // |
489 | class MdaExceptionSwallowedOnCallFromCom |
490 | { |
491 | public: |
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 | // |
502 | class MdaInvalidVariant |
503 | { |
504 | public: |
505 | void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; } |
506 | void ReportViolation(); |
507 | |
508 | MDA_ASSISTANT_BASE_MEMBERS; |
509 | }; |
510 | |
511 | |
512 | // |
513 | // MdaInvalidApartmentStateChange |
514 | // |
515 | class MdaInvalidApartmentStateChange |
516 | { |
517 | public: |
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 | // |
529 | HRESULT MdaFailedQIAssistantCallback(LPVOID pData); |
530 | |
531 | typedef struct |
532 | { |
533 | RCW* pWrapper; |
534 | IID iid; |
535 | BOOL fSuccess; |
536 | } MdaFailedQIAssistantCallbackData; |
537 | |
538 | #define OLE32DLL W("ole32.dll") |
539 | |
540 | class MdaFailedQI |
541 | { |
542 | public: |
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 | // |
553 | class MdaDisconnectedContext |
554 | { |
555 | public: |
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 | // |
567 | class MdaNotMarshalable |
568 | { |
569 | public: |
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 | // |
581 | class MdaMarshalCleanupError |
582 | { |
583 | public: |
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 | // |
597 | class MdaInvalidIUnknown |
598 | { |
599 | public: |
600 | void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; } |
601 | void ReportViolation(); |
602 | |
603 | MDA_ASSISTANT_BASE_MEMBERS; |
604 | }; |
605 | |
606 | |
607 | // |
608 | // MdaContextSwitchDeadlock |
609 | // |
610 | class MdaContextSwitchDeadlock |
611 | { |
612 | public: |
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 | // |
623 | class MdaRaceOnRCWCleanup |
624 | { |
625 | public: |
626 | void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; } |
627 | void ReportViolation(); |
628 | |
629 | MDA_ASSISTANT_BASE_MEMBERS; |
630 | }; |
631 | |
632 | // |
633 | // MdaMarshaling |
634 | // |
635 | class MdaMarshaling |
636 | { |
637 | public: |
638 | void Initialize(MdaXmlElement* pXmlInput); |
639 | void ReportFieldMarshal(FieldMarshaler* pFM); |
640 | |
641 | private: |
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 | |
648 | public: |
649 | MDA_ASSISTANT_BASE_MEMBERS; |
650 | MdaQuery::CompiledQueries* m_pMethodFilter; |
651 | MdaQuery::CompiledQueries* m_pFieldFilter; |
652 | }; |
653 | |
654 | |
655 | |
656 | // |
657 | // InvalidFunctionPointerInDelegate |
658 | // |
659 | class MdaInvalidFunctionPointerInDelegate |
660 | { |
661 | public: |
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 | // |
672 | class MdaDirtyCastAndCallOnInterface |
673 | { |
674 | public: |
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 | // |
685 | class MdaInvalidCERCall |
686 | { |
687 | public: |
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 | // |
699 | class MdaVirtualCERCall |
700 | { |
701 | public: |
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 | // |
713 | class MdaOpenGenericCERCall |
714 | { |
715 | public: |
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 | // |
727 | class MdaIllegalPrepareConstrainedRegion |
728 | { |
729 | public: |
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 | // |
741 | class MdaReleaseHandleFailed |
742 | { |
743 | public: |
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 | // |
754 | class MdaNonComVisibleBaseClass |
755 | { |
756 | public: |
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 | // |
769 | class MdaInvalidGCHandleCookie |
770 | { |
771 | public: |
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 | // |
781 | class MdaXmlValidator |
782 | { |
783 | public: |
784 | void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; } |
785 | |
786 | MDA_ASSISTANT_BASE_MEMBERS; |
787 | }; |
788 | |
789 | |
790 | #ifdef _DEBUG |
791 | // |
792 | // MdaXmlValidationError |
793 | // |
794 | class MdaXmlValidationError |
795 | { |
796 | public: |
797 | void Initialize(MdaXmlElement* pXml) { LIMITED_METHOD_CONTRACT; } |
798 | |
799 | public: |
800 | void ReportError(MdaSchema::ValidationResult* pValidationResult); |
801 | |
802 | MDA_ASSISTANT_BASE_MEMBERS; |
803 | }; |
804 | #endif |
805 | |
806 | |
807 | // |
808 | // MdaInvalidConfigFile |
809 | // |
810 | class MdaInvalidConfigFile |
811 | { |
812 | public: |
813 | void Initialize(MdaXmlElement* pXml) { LIMITED_METHOD_CONTRACT; } |
814 | |
815 | public: |
816 | void ReportError(MdaElemDeclDef configFile); |
817 | |
818 | MDA_ASSISTANT_BASE_MEMBERS; |
819 | }; |
820 | |
821 | // |
822 | // MdaDateTimeInvalidLocalFormat |
823 | // |
824 | class MdaDateTimeInvalidLocalFormat |
825 | { |
826 | public: |
827 | void Initialize(MdaXmlElement* pXmlInput) { LIMITED_METHOD_CONTRACT; } |
828 | void ReportError(); |
829 | |
830 | MDA_ASSISTANT_BASE_MEMBERS; |
831 | }; |
832 | |
833 | // |
834 | // MdaStreamWriterBufferedDataLost |
835 | // |
836 | class MdaStreamWriterBufferedDataLost |
837 | { |
838 | public: |
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 | |
859 | class 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 | |
871 | typedef 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 | } |
893 | MdaStaticHeap; |
894 | typedef DPTR(MdaStaticHeap) PTR_MdaStaticHeap; |
895 | extern MdaStaticHeap g_mdaStaticHeap; |
896 | |
897 | |
898 | // static |
899 | FORCEINLINE void ManagedDebuggingAssistants::Enable(MdaElemDeclDef assistantDeclDef, MdaAssistant* pMda) |
900 | { |
901 | g_mdaStaticHeap.m_assistants[assistantDeclDef] = pMda; |
902 | } |
903 | |
904 | #ifndef DACCESS_COMPILE |
905 | FORCEINLINE 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 | |
915 | FORCEINLINE 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 | |
927 | void TriggerGCForMDAInternal(); |
928 | |
929 | #endif // MDA_SUPPORTED |
930 | #endif // _MDA_ASSISTANTS_ |
931 | |
932 | |
933 | |