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 //*****************************************************************************
6 // Internal data access functionality.
8 //*****************************************************************************
10 #ifndef _DACPRIVATE_H_
11 #define _DACPRIVATE_H_
19 // It is unfortunate having to include this header just to get the definition of GenericModeBlock
24 // Whenever a structure is marshalled between different platforms, we need to ensure the
25 // layout is the same in both cases. We tell GCC to use the MSVC-style packing with
26 // the following attribute. The main thing this appears to control is whether
27 // 8-byte values are aligned at 4-bytes (GCC default) or 8-bytes (MSVC default).
28 // This attribute affects only the immediate struct it is applied to, you must also apply
29 // it to any nested structs if you want their layout affected as well. You also must
30 // apply this to unions embedded in other structures, since it can influence the starting
33 // Note that there doesn't appear to be any disadvantage to applying this a little
34 // more agressively than necessary, so we generally use it on all classes / structures
35 // defined in a file that defines marshalled data types (eg. DacDbiStructures.h)
36 // The -mms-bitfields compiler option also does this for the whole file, but we don't
37 // want to go changing the layout of, for example, structures defined in OS header files
38 // so we explicitly opt-in with this attribute.
41 #define MSLAYOUT __attribute__((__ms_struct__))
46 //----------------------------------------------------------------------------
48 // Utility class to allow for zero initialization of our Dacp- structs.
50 //----------------------------------------------------------------------------
56 { memset(static_cast<T*>(this), 0, sizeof(T)); }
60 #include <livedatatarget.h>
62 //----------------------------------------------------------------------------
64 // Internal CLRData requests.
66 //----------------------------------------------------------------------------
69 // Private requests for DataModules
72 DACDATAMODULEPRIV_REQUEST_GET_MODULEPTR = 0xf0000000,
73 DACDATAMODULEPRIV_REQUEST_GET_MODULEDATA = 0xf0000001
77 // Private requests for stack walkers.
80 DACSTACKPRIV_REQUEST_FRAME_DATA = 0xf0000000
83 enum DacpObjectType { OBJ_STRING=0,OBJ_FREE,OBJ_OBJECT,OBJ_ARRAY,OBJ_OTHER };
84 struct MSLAYOUT DacpObjectData : ZeroInit<DacpObjectData>
86 CLRDATA_ADDRESS MethodTable;
87 DacpObjectType ObjectType;
89 CLRDATA_ADDRESS ElementTypeHandle;
90 CorElementType ElementType;
92 ULONG64 dwNumComponents;
93 ULONG64 dwComponentSize;
94 CLRDATA_ADDRESS ArrayDataPtr;
95 CLRDATA_ADDRESS ArrayBoundsPtr;
96 CLRDATA_ADDRESS ArrayLowerBoundsPtr;
101 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
103 return sos->GetObjectData(addr, this);
107 struct MSLAYOUT DacpExceptionObjectData : ZeroInit<DacpExceptionObjectData>
109 CLRDATA_ADDRESS Message;
110 CLRDATA_ADDRESS InnerException;
111 CLRDATA_ADDRESS StackTrace;
112 CLRDATA_ADDRESS WatsonBuckets;
113 CLRDATA_ADDRESS StackTraceString;
114 CLRDATA_ADDRESS RemoteStackTraceString;
118 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
121 ISOSDacInterface2 *psos2 = NULL;
122 if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface2), (void**) &psos2)))
124 hr = psos2->GetObjectExceptionData(addr, this);
131 struct MSLAYOUT DacpUsefulGlobalsData : ZeroInit<DacpUsefulGlobalsData>
133 CLRDATA_ADDRESS ArrayMethodTable;
134 CLRDATA_ADDRESS StringMethodTable;
135 CLRDATA_ADDRESS ObjectMethodTable;
136 CLRDATA_ADDRESS ExceptionMethodTable;
137 CLRDATA_ADDRESS FreeMethodTable;
140 struct MSLAYOUT DacpFieldDescData : ZeroInit<DacpFieldDescData>
143 CorElementType sigType; // ELEMENT_TYPE_XXX from signature. We need this to disply pretty name for String in minidump's case
144 CLRDATA_ADDRESS MTOfType; // NULL if Type is not loaded
146 CLRDATA_ADDRESS ModuleOfType;
147 mdTypeDef TokenOfType;
150 CLRDATA_ADDRESS MTOfEnclosingClass;
153 BOOL bIsContextLocal;
155 CLRDATA_ADDRESS NextField;
157 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
159 return sos->GetFieldDescData(addr, this);
163 struct MSLAYOUT DacpMethodTableFieldData : ZeroInit<DacpMethodTableFieldData>
165 WORD wNumInstanceFields;
166 WORD wNumStaticFields;
167 WORD wNumThreadStaticFields;
169 CLRDATA_ADDRESS FirstField; // If non-null, you can retrieve more
171 WORD wContextStaticOffset;
172 WORD wContextStaticsSize;
174 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
176 return sos->GetMethodTableFieldData(addr, this);
180 struct MSLAYOUT DacpMethodTableTransparencyData : ZeroInit<DacpMethodTableTransparencyData>
182 BOOL bHasCriticalTransparentInfo;
186 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
188 return sos->GetMethodTableTransparencyData(addr, this);
192 struct MSLAYOUT DacpDomainLocalModuleData : ZeroInit<DacpDomainLocalModuleData>
194 // These two parameters are used as input params when calling the
195 // no-argument form of Request below.
196 CLRDATA_ADDRESS appDomainAddr;
199 CLRDATA_ADDRESS pClassData;
200 CLRDATA_ADDRESS pDynamicClassTable;
201 CLRDATA_ADDRESS pGCStaticDataStart;
202 CLRDATA_ADDRESS pNonGCStaticDataStart;
204 // Called when you have a pointer to the DomainLocalModule
205 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
207 return sos->GetDomainLocalModuleData(addr, this);
212 struct MSLAYOUT DacpThreadLocalModuleData : ZeroInit<DacpThreadLocalModuleData>
214 // These two parameters are used as input params when calling the
215 // no-argument form of Request below.
216 CLRDATA_ADDRESS threadAddr;
219 CLRDATA_ADDRESS pClassData;
220 CLRDATA_ADDRESS pDynamicClassTable;
221 CLRDATA_ADDRESS pGCStaticDataStart;
222 CLRDATA_ADDRESS pNonGCStaticDataStart;
226 struct MSLAYOUT DacpModuleData : ZeroInit<DacpModuleData>
228 CLRDATA_ADDRESS Address;
229 CLRDATA_ADDRESS File; // A PEFile addr
230 CLRDATA_ADDRESS ilBase;
231 CLRDATA_ADDRESS metadataStart;
232 ULONG64 metadataSize;
233 CLRDATA_ADDRESS Assembly; // Assembly pointer
236 ULONG64 dwBaseClassIndex;
239 DWORD dwTransientFlags;
241 CLRDATA_ADDRESS TypeDefToMethodTableMap;
242 CLRDATA_ADDRESS TypeRefToMethodTableMap;
243 CLRDATA_ADDRESS MethodDefToDescMap;
244 CLRDATA_ADDRESS FieldDefToDescMap;
245 CLRDATA_ADDRESS MemberRefToDescMap;
246 CLRDATA_ADDRESS FileReferencesMap;
247 CLRDATA_ADDRESS ManifestModuleReferencesMap;
249 CLRDATA_ADDRESS pLookupTableHeap;
250 CLRDATA_ADDRESS pThunkHeap;
252 ULONG64 dwModuleIndex;
258 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
260 return sos->GetModuleData(addr, this);
264 // Ensure that this data structure is not copied.
265 DacpModuleData(const DacpModuleData&);
266 void operator=(const DacpModuleData&);
269 struct MSLAYOUT DacpMethodTableData : ZeroInit<DacpMethodTableData>
271 BOOL bIsFree; // everything else is NULL if this is true.
272 CLRDATA_ADDRESS Module;
273 CLRDATA_ADDRESS Class;
274 CLRDATA_ADDRESS ParentMethodTable;
277 WORD wNumVtableSlots;
281 mdTypeDef cl; // Metadata token
282 DWORD dwAttrClass; // cached metadata
283 BOOL bIsShared; // flags & enum_flag_DomainNeutral
285 BOOL bContainsPointers;
287 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
289 return sos->GetMethodTableData(addr, this);
294 // Copied from util.hpp, for DacpThreadStoreData.fHostConfig below.
295 #define CLRMEMORYHOSTED 0x1
296 #define CLRTASKHOSTED 0x2
297 #define CLRSYNCHOSTED 0x4
298 #define CLRTHREADPOOLHOSTED 0x8
299 #define CLRIOCOMPLETIONHOSTED 0x10
300 #define CLRASSEMBLYHOSTED 0x20
301 #define CLRGCHOSTED 0x40
302 #define CLRSECURITYHOSTED 0x80
303 #define CLRHOSTED 0x80000000
305 struct MSLAYOUT DacpThreadStoreData : ZeroInit<DacpThreadStoreData>
308 LONG unstartedThreadCount;
309 LONG backgroundThreadCount;
310 LONG pendingThreadCount;
311 LONG deadThreadCount;
312 CLRDATA_ADDRESS firstThread;
313 CLRDATA_ADDRESS finalizerThread;
314 CLRDATA_ADDRESS gcThread;
315 DWORD fHostConfig; // Uses hosting flags defined above
317 HRESULT Request(ISOSDacInterface *sos)
319 return sos->GetThreadStoreData(this);
323 struct MSLAYOUT DacpAppDomainStoreData : ZeroInit<DacpAppDomainStoreData>
325 CLRDATA_ADDRESS sharedDomain;
326 CLRDATA_ADDRESS systemDomain;
329 HRESULT Request(ISOSDacInterface *sos)
331 return sos->GetAppDomainStoreData(this);
335 struct MSLAYOUT DacpCOMInterfacePointerData : ZeroInit<DacpCOMInterfacePointerData>
337 CLRDATA_ADDRESS methodTable;
338 CLRDATA_ADDRESS interfacePtr;
339 CLRDATA_ADDRESS comContext;
342 struct MSLAYOUT DacpRCWData : ZeroInit<DacpRCWData>
344 CLRDATA_ADDRESS identityPointer;
345 CLRDATA_ADDRESS unknownPointer;
346 CLRDATA_ADDRESS managedObject;
347 CLRDATA_ADDRESS jupiterObject;
348 CLRDATA_ADDRESS vtablePtr;
349 CLRDATA_ADDRESS creatorThread;
350 CLRDATA_ADDRESS ctxCookie;
355 BOOL isJupiterObject;
356 BOOL supportsIInspectable;
362 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS rcw)
364 return sos->GetRCWData(rcw, this);
367 HRESULT IsDCOMProxy(ISOSDacInterface *sos, CLRDATA_ADDRESS rcw, BOOL* isDCOMProxy)
369 ISOSDacInterface2 *pSOS2 = nullptr;
370 HRESULT hr = sos->QueryInterface(__uuidof(ISOSDacInterface2), reinterpret_cast<LPVOID*>(&pSOS2));
373 hr = pSOS2->IsRCWDCOMProxy(rcw, isDCOMProxy);
381 struct MSLAYOUT DacpCCWData : ZeroInit<DacpCCWData>
383 CLRDATA_ADDRESS outerIUnknown;
384 CLRDATA_ADDRESS managedObject;
385 CLRDATA_ADDRESS handle;
386 CLRDATA_ADDRESS ccwAddress;
392 LONG jupiterRefCount;
396 BOOL isExtendsCOMObject;
399 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS ccw)
401 return sos->GetCCWData(ccw, this);
405 enum DacpAppDomainDataStage {
407 STAGE_READYFORMANAGEDCODE,
410 STAGE_UNLOAD_REQUESTED,
415 STAGE_HANDLETABLE_NOACCESS,
421 // Information about a BaseDomain (AppDomain, SharedDomain or SystemDomain).
422 // For types other than AppDomain, some fields (like dwID, DomainLocalBlock, etc.) will be 0/null.
423 struct MSLAYOUT DacpAppDomainData : ZeroInit<DacpAppDomainData>
425 // The pointer to the BaseDomain (not necessarily an AppDomain).
426 // It's useful to keep this around in the structure
427 CLRDATA_ADDRESS AppDomainPtr;
428 CLRDATA_ADDRESS AppSecDesc;
429 CLRDATA_ADDRESS pLowFrequencyHeap;
430 CLRDATA_ADDRESS pHighFrequencyHeap;
431 CLRDATA_ADDRESS pStubHeap;
432 CLRDATA_ADDRESS DomainLocalBlock;
433 CLRDATA_ADDRESS pDomainLocalModules;
434 // The creation sequence number of this app domain (starting from 1)
437 LONG FailedAssemblyCount;
438 DacpAppDomainDataStage appDomainStage;
440 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
442 return sos->GetAppDomainData(addr, this);
446 struct MSLAYOUT DacpAssemblyData : ZeroInit<DacpAssemblyData>
448 CLRDATA_ADDRESS AssemblyPtr; //useful to have
449 CLRDATA_ADDRESS ClassLoader;
450 CLRDATA_ADDRESS ParentDomain;
451 CLRDATA_ADDRESS BaseDomainPtr;
452 CLRDATA_ADDRESS AssemblySecDesc;
456 BOOL isDomainNeutral;
457 DWORD dwLocationFlags;
459 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr, CLRDATA_ADDRESS baseDomainPtr)
461 return sos->GetAssemblyData(baseDomainPtr, addr, this);
464 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
466 return Request(sos, addr, NULL);
471 struct MSLAYOUT DacpThreadData : ZeroInit<DacpThreadData>
476 ULONG preemptiveGCDisabled;
477 CLRDATA_ADDRESS allocContextPtr;
478 CLRDATA_ADDRESS allocContextLimit;
479 CLRDATA_ADDRESS context;
480 CLRDATA_ADDRESS domain;
481 CLRDATA_ADDRESS pFrame;
483 CLRDATA_ADDRESS firstNestedException; // Pass this pointer to DacpNestedExceptionInfo
485 CLRDATA_ADDRESS fiberData;
486 CLRDATA_ADDRESS lastThrownObjectHandle;
487 CLRDATA_ADDRESS nextThread;
489 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
491 return sos->GetThreadData(addr, this);
496 struct MSLAYOUT DacpReJitData : ZeroInit<DacpReJitData>
506 CLRDATA_ADDRESS rejitID;
508 CLRDATA_ADDRESS NativeCodeAddr;
512 struct MSLAYOUT DacpMethodDescData : ZeroInit<DacpMethodDescData>
517 CLRDATA_ADDRESS NativeCodeAddr;
518 // Useful for breaking when a method is jitted.
519 CLRDATA_ADDRESS AddressOfNativeCodeSlot;
521 CLRDATA_ADDRESS MethodDescPtr;
522 CLRDATA_ADDRESS MethodTablePtr;
523 CLRDATA_ADDRESS ModulePtr;
526 CLRDATA_ADDRESS GCInfo;
527 CLRDATA_ADDRESS GCStressCodeCopy;
529 // This is only valid if bIsDynamic is true
530 CLRDATA_ADDRESS managedDynamicMethodObject;
532 CLRDATA_ADDRESS requestedIP;
534 // Gives info for the single currently active version of a method
535 DacpReJitData rejitDataCurrent;
537 // Gives info corresponding to requestedIP (for !ip2md)
538 DacpReJitData rejitDataRequested;
540 // Total number of rejit versions that have been jitted
541 ULONG cJittedRejitVersions;
543 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
545 return sos->GetMethodDescData(
551 NULL // pcNeededRejitData
557 struct MSLAYOUT DacpMethodDescTransparencyData : ZeroInit<DacpMethodDescTransparencyData>
559 BOOL bHasCriticalTransparentInfo;
563 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
565 return sos->GetMethodDescTransparencyData(addr, this);
569 struct MSLAYOUT DacpTieredVersionData
579 CLRDATA_ADDRESS NativeCodeAddr;
580 TieredState TieredInfo;
581 CLRDATA_ADDRESS NativeCodeVersionNodePtr;
585 enum JITTypes {TYPE_UNKNOWN=0,TYPE_JIT,TYPE_PJIT};
587 struct MSLAYOUT DacpCodeHeaderData : ZeroInit<DacpCodeHeaderData>
589 CLRDATA_ADDRESS GCInfo;
591 CLRDATA_ADDRESS MethodDescPtr;
592 CLRDATA_ADDRESS MethodStart;
594 CLRDATA_ADDRESS ColdRegionStart;
595 DWORD ColdRegionSize;
598 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS IPAddr)
600 return sos->GetCodeHeaderData(IPAddr, this);
604 struct MSLAYOUT DacpWorkRequestData : ZeroInit<DacpWorkRequestData>
606 CLRDATA_ADDRESS Function;
607 CLRDATA_ADDRESS Context;
608 CLRDATA_ADDRESS NextWorkRequest;
610 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
612 return sos->GetWorkRequestData(addr, this);
616 struct MSLAYOUT DacpHillClimbingLogEntry : ZeroInit<DacpHillClimbingLogEntry>
620 int NewControlSetting;
621 int LastHistoryCount;
622 double LastHistoryMean;
624 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS entry)
626 return sos->GetHillClimbingLogEntry(entry, this);
631 // Used for CLR versions >= 4.0
632 struct MSLAYOUT DacpThreadpoolData : ZeroInit<DacpThreadpoolData>
635 int NumIdleWorkerThreads;
636 int NumWorkingWorkerThreads;
637 int NumRetiredWorkerThreads;
638 LONG MinLimitTotalWorkerThreads;
639 LONG MaxLimitTotalWorkerThreads;
641 CLRDATA_ADDRESS FirstUnmanagedWorkRequest;
643 CLRDATA_ADDRESS HillClimbingLog;
644 int HillClimbingLogFirstIndex;
645 int HillClimbingLogSize;
648 // TODO: Add support to enumerate timers too.
651 LONG NumFreeCPThreads;
652 LONG MaxFreeCPThreads;
653 LONG NumRetiredCPThreads;
654 LONG MaxLimitTotalCPThreads;
655 LONG CurrentLimitTotalCPThreads;
656 LONG MinLimitTotalCPThreads;
658 CLRDATA_ADDRESS AsyncTimerCallbackCompletionFPtr;
660 HRESULT Request(ISOSDacInterface *sos)
662 return sos->GetThreadpoolData(this);
666 struct MSLAYOUT DacpGenerationData : ZeroInit<DacpGenerationData>
668 CLRDATA_ADDRESS start_segment;
669 CLRDATA_ADDRESS allocation_start;
671 // These are examined only for generation 0, otherwise NULL
672 CLRDATA_ADDRESS allocContextPtr;
673 CLRDATA_ADDRESS allocContextLimit;
676 #define DAC_NUMBERGENERATIONS 4
679 struct MSLAYOUT DacpAllocData : ZeroInit<DacpAllocData>
681 CLRDATA_ADDRESS allocBytes;
682 CLRDATA_ADDRESS allocBytesLoh;
685 struct MSLAYOUT DacpGenerationAllocData : ZeroInit<DacpGenerationAllocData>
687 DacpAllocData allocData[DAC_NUMBERGENERATIONS];
690 struct MSLAYOUT DacpGcHeapDetails : ZeroInit<DacpGcHeapDetails>
692 CLRDATA_ADDRESS heapAddr; // Only filled in in server mode, otherwise NULL
693 CLRDATA_ADDRESS alloc_allocated;
695 CLRDATA_ADDRESS mark_array;
696 CLRDATA_ADDRESS current_c_gc_state;
697 CLRDATA_ADDRESS next_sweep_obj;
698 CLRDATA_ADDRESS saved_sweep_ephemeral_seg;
699 CLRDATA_ADDRESS saved_sweep_ephemeral_start;
700 CLRDATA_ADDRESS background_saved_lowest_address;
701 CLRDATA_ADDRESS background_saved_highest_address;
703 DacpGenerationData generation_table [DAC_NUMBERGENERATIONS];
704 CLRDATA_ADDRESS ephemeral_heap_segment;
705 CLRDATA_ADDRESS finalization_fill_pointers [DAC_NUMBERGENERATIONS + 3];
706 CLRDATA_ADDRESS lowest_address;
707 CLRDATA_ADDRESS highest_address;
708 CLRDATA_ADDRESS card_table;
710 // Use this for workstation mode (DacpGcHeapDat.bServerMode==FALSE).
711 HRESULT Request(ISOSDacInterface *sos)
713 return sos->GetGCHeapStaticData(this);
716 // Use this for Server mode, as there are multiple heaps,
717 // and you need to pass a heap address in addr.
718 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
720 return sos->GetGCHeapDetails(addr, this);
724 struct MSLAYOUT DacpGcHeapData
725 : ZeroInit<DacpGcHeapData>
728 BOOL bGcStructuresValid;
730 UINT g_max_generation;
732 HRESULT Request(ISOSDacInterface *sos)
734 return sos->GetGCHeapData(this);
738 struct MSLAYOUT DacpHeapSegmentData
739 : ZeroInit<DacpHeapSegmentData>
741 CLRDATA_ADDRESS segmentAddr;
742 CLRDATA_ADDRESS allocated;
743 CLRDATA_ADDRESS committed;
744 CLRDATA_ADDRESS reserved;
745 CLRDATA_ADDRESS used;
747 // pass this to request if non-null to get the next segments.
748 CLRDATA_ADDRESS next;
749 CLRDATA_ADDRESS gc_heap; // only filled in in server mode, otherwise NULL
750 // computed field: if this is the ephemeral segment highMark includes the ephemeral generation
751 CLRDATA_ADDRESS highAllocMark;
754 CLRDATA_ADDRESS background_allocated;
756 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr, const DacpGcHeapDetails& heap)
758 HRESULT hr = sos->GetHeapSegmentData(addr, this);
760 // if this is the start segment, set highAllocMark too.
763 // TODO: This needs to be put on the Dac side.
764 if (this->segmentAddr == heap.generation_table[0].start_segment)
765 highAllocMark = heap.alloc_allocated;
767 highAllocMark = allocated;
773 struct MSLAYOUT DacpOomData : ZeroInit<DacpOomData>
777 ULONG64 available_pagefile_mb;
783 HRESULT Request(ISOSDacInterface *sos)
785 return sos->GetOOMStaticData(this);
788 // Use this for Server mode, as there are multiple heaps,
789 // and you need to pass a heap address in addr.
790 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
792 return sos->GetOOMData(addr, this);
796 #define DAC_NUM_GC_DATA_POINTS 9
797 #define DAC_MAX_COMPACT_REASONS_COUNT 11
798 #define DAC_MAX_EXPAND_MECHANISMS_COUNT 6
799 #define DAC_MAX_GC_MECHANISM_BITS_COUNT 2
800 #define DAC_MAX_GLOBAL_GC_MECHANISMS_COUNT 6
801 struct MSLAYOUT DacpGCInterestingInfoData : ZeroInit<DacpGCInterestingInfoData>
803 size_t interestingDataPoints[DAC_NUM_GC_DATA_POINTS];
804 size_t compactReasons[DAC_MAX_COMPACT_REASONS_COUNT];
805 size_t expandMechanisms[DAC_MAX_EXPAND_MECHANISMS_COUNT];
806 size_t bitMechanisms[DAC_MAX_GC_MECHANISM_BITS_COUNT];
807 size_t globalMechanisms[DAC_MAX_GLOBAL_GC_MECHANISMS_COUNT];
809 HRESULT RequestGlobal(ISOSDacInterface *sos)
812 ISOSDacInterface3 *psos3 = NULL;
813 if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3)))
815 hr = psos3->GetGCGlobalMechanisms(globalMechanisms);
821 HRESULT Request(ISOSDacInterface *sos)
824 ISOSDacInterface3 *psos3 = NULL;
825 if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3)))
827 hr = psos3->GetGCInterestingInfoStaticData(this);
833 // Use this for Server mode, as there are multiple heaps,
834 // and you need to pass a heap address in addr.
835 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
838 ISOSDacInterface3 *psos3 = NULL;
839 if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3)))
841 hr = psos3->GetGCInterestingInfoData(addr, this);
848 struct MSLAYOUT DacpGcHeapAnalyzeData
849 : ZeroInit<DacpGcHeapAnalyzeData>
851 CLRDATA_ADDRESS heapAddr; // Only filled in in server mode, otherwise NULL
853 CLRDATA_ADDRESS internal_root_array;
854 ULONG64 internal_root_array_index;
855 BOOL heap_analyze_success;
857 // Use this for workstation mode (DacpGcHeapDat.bServerMode==FALSE).
858 HRESULT Request(ISOSDacInterface *sos)
860 return sos->GetHeapAnalyzeStaticData(this);
863 // Use this for Server mode, as there are multiple heaps,
864 // and you need to pass a heap address in addr.
865 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
867 return sos->GetHeapAnalyzeData(addr, this);
872 #define SYNCBLOCKDATA_COMFLAGS_CCW 1
873 #define SYNCBLOCKDATA_COMFLAGS_RCW 2
874 #define SYNCBLOCKDATA_COMFLAGS_CF 4
876 struct MSLAYOUT DacpSyncBlockData : ZeroInit<DacpSyncBlockData>
878 CLRDATA_ADDRESS Object;
879 BOOL bFree; // if set, no other fields are useful
881 // fields below provide data from this, so it's just for display
882 CLRDATA_ADDRESS SyncBlockPointer;
886 CLRDATA_ADDRESS HoldingThread;
887 UINT AdditionalThreadCount;
888 CLRDATA_ADDRESS appDomainPtr;
890 // SyncBlockCount will always be filled in with the number of SyncBlocks.
891 // SyncBlocks may be requested from [1,SyncBlockCount]
894 // SyncBlockNumber must be from [1,SyncBlockCount]
895 // If there are no SyncBlocks, a call to Request with SyncBlockCount = 1
896 // will return E_FAIL.
897 HRESULT Request(ISOSDacInterface *sos, UINT SyncBlockNumber)
899 return sos->GetSyncBlockData(SyncBlockNumber, this);
903 struct MSLAYOUT DacpSyncBlockCleanupData : ZeroInit<DacpSyncBlockCleanupData>
905 CLRDATA_ADDRESS SyncBlockPointer;
907 CLRDATA_ADDRESS nextSyncBlock;
908 CLRDATA_ADDRESS blockRCW;
909 CLRDATA_ADDRESS blockClassFactory;
910 CLRDATA_ADDRESS blockCCW;
912 // Pass NULL on the first request to start a traversal.
913 HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS psyncBlock)
915 return sos->GetSyncBlockCleanupData(psyncBlock, this);
919 ///////////////////////////////////////////////////////////////////////////
921 enum EHClauseType {EHFault, EHFinally, EHFilter, EHTyped, EHUnknown};
923 struct MSLAYOUT DACEHInfo : ZeroInit<DACEHInfo>
925 EHClauseType clauseType;
926 CLRDATA_ADDRESS tryStartOffset;
927 CLRDATA_ADDRESS tryEndOffset;
928 CLRDATA_ADDRESS handlerStartOffset;
929 CLRDATA_ADDRESS handlerEndOffset;
930 BOOL isDuplicateClause;
931 CLRDATA_ADDRESS filterOffset; // valid when clauseType is EHFilter
932 BOOL isCatchAllHandler; // valid when clauseType is EHTyped
933 CLRDATA_ADDRESS moduleAddr; // when == 0 mtCatch contains a MethodTable, when != 0 tokCatch contains a type token
934 CLRDATA_ADDRESS mtCatch; // the method table of the TYPED clause type
935 mdToken tokCatch; // the type token of the TYPED clause type
938 struct MSLAYOUT DacpGetModuleAddress : ZeroInit<DacpGetModuleAddress>
940 CLRDATA_ADDRESS ModulePtr;
941 HRESULT Request(IXCLRDataModule* pDataModule)
943 return pDataModule->Request(DACDATAMODULEPRIV_REQUEST_GET_MODULEPTR, 0, NULL, sizeof(*this), (PBYTE) this);
947 struct MSLAYOUT DacpGetModuleData : ZeroInit<DacpGetModuleData>
952 CLRDATA_ADDRESS PEFile;
953 CLRDATA_ADDRESS LoadedPEAddress;
954 ULONG64 LoadedPESize;
955 CLRDATA_ADDRESS InMemoryPdbAddress;
956 ULONG64 InMemoryPdbSize;
958 HRESULT Request(IXCLRDataModule* pDataModule)
960 return pDataModule->Request(DACDATAMODULEPRIV_REQUEST_GET_MODULEDATA, 0, NULL, sizeof(*this), (PBYTE) this);
964 struct MSLAYOUT DacpFrameData : ZeroInit<DacpFrameData>
966 CLRDATA_ADDRESS frameAddr;
968 // Could also be implemented for IXCLRDataFrame if desired.
969 HRESULT Request(IXCLRDataStackWalk* dac)
971 return dac->Request(DACSTACKPRIV_REQUEST_FRAME_DATA,
973 sizeof(*this), (PBYTE)this);
977 struct MSLAYOUT DacpJitManagerInfo : ZeroInit<DacpJitManagerInfo>
979 CLRDATA_ADDRESS managerAddr;
980 DWORD codeType; // for union below
981 CLRDATA_ADDRESS ptrHeapList; // A HeapList * if IsMiIL(codeType)
984 enum CodeHeapType {CODEHEAP_LOADER=0,CODEHEAP_HOST,CODEHEAP_UNKNOWN};
986 struct MSLAYOUT DacpJitCodeHeapInfo : ZeroInit<DacpJitCodeHeapInfo>
988 DWORD codeHeapType; // for union below
992 CLRDATA_ADDRESS LoaderHeap; // if CODEHEAP_LOADER
995 CLRDATA_ADDRESS baseAddr; // if CODEHEAP_HOST
996 CLRDATA_ADDRESS currentAddr;
1001 #include "static_assert.h"
1003 /* DAC datastructures are frozen as of dev11 shipping. Do NOT add fields, remove fields, or change the fields of
1004 * these structs in any way. The correct way to get new data out of the runtime is to create a new struct and
1005 * add a new function to the latest Dac<-->SOS interface to produce this data.
1007 static_assert(sizeof(DacpAllocData) == 0x10, "Dacp structs cannot be modified due to backwards compatibility.");
1008 static_assert(sizeof(DacpGenerationAllocData) == 0x40, "Dacp structs cannot be modified due to backwards compatibility.");
1009 static_assert(sizeof(DacpSyncBlockCleanupData) == 0x28, "Dacp structs cannot be modified due to backwards compatibility.");
1010 static_assert(sizeof(DacpThreadStoreData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility.");
1011 static_assert(sizeof(DacpAppDomainStoreData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1012 static_assert(sizeof(DacpAppDomainData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility.");
1013 static_assert(sizeof(DacpAssemblyData) == 0x40, "Dacp structs cannot be modified due to backwards compatibility.");
1014 static_assert(sizeof(DacpThreadData) == 0x68, "Dacp structs cannot be modified due to backwards compatibility.");
1015 static_assert(sizeof(DacpMethodDescData) == 0x98, "Dacp structs cannot be modified due to backwards compatibility.");
1016 static_assert(sizeof(DacpCodeHeaderData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility.");
1017 static_assert(sizeof(DacpThreadpoolData) == 0x58, "Dacp structs cannot be modified due to backwards compatibility.");
1018 static_assert(sizeof(DacpObjectData) == 0x60, "Dacp structs cannot be modified due to backwards compatibility.");
1019 static_assert(sizeof(DacpMethodTableData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility.");
1020 static_assert(sizeof(DacpWorkRequestData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1021 static_assert(sizeof(DacpFieldDescData) == 0x40, "Dacp structs cannot be modified due to backwards compatibility.");
1022 static_assert(sizeof(DacpModuleData) == 0xa0, "Dacp structs cannot be modified due to backwards compatibility.");
1023 static_assert(sizeof(DacpGcHeapData) == 0x10, "Dacp structs cannot be modified due to backwards compatibility.");
1024 static_assert(sizeof(DacpJitManagerInfo) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1025 static_assert(sizeof(DacpHeapSegmentData) == 0x58, "Dacp structs cannot be modified due to backwards compatibility.");
1026 static_assert(sizeof(DacpDomainLocalModuleData) == 0x30, "Dacp structs cannot be modified due to backwards compatibility.");
1027 static_assert(sizeof(DacpUsefulGlobalsData) == 0x28, "Dacp structs cannot be modified due to backwards compatibility.");
1028 static_assert(sizeof(DACEHInfo) == 0x58, "Dacp structs cannot be modified due to backwards compatibility.");
1029 static_assert(sizeof(DacpRCWData) == 0x58, "Dacp structs cannot be modified due to backwards compatibility.");
1030 static_assert(sizeof(DacpCCWData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility.");
1031 static_assert(sizeof(DacpMethodTableFieldData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1032 static_assert(sizeof(DacpMethodTableTransparencyData) == 0xc, "Dacp structs cannot be modified due to backwards compatibility.");
1033 static_assert(sizeof(DacpThreadLocalModuleData) == 0x30, "Dacp structs cannot be modified due to backwards compatibility.");
1034 static_assert(sizeof(DacpCOMInterfacePointerData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1035 static_assert(sizeof(DacpMethodDescTransparencyData) == 0xc, "Dacp structs cannot be modified due to backwards compatibility.");
1036 static_assert(sizeof(DacpHillClimbingLogEntry) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1037 static_assert(sizeof(DacpGenerationData) == 0x20, "Dacp structs cannot be modified due to backwards compatibility.");
1038 static_assert(sizeof(DacpGcHeapDetails) == 0x120, "Dacp structs cannot be modified due to backwards compatibility.");
1039 static_assert(sizeof(DacpOomData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility.");
1040 static_assert(sizeof(DacpGcHeapAnalyzeData) == 0x20, "Dacp structs cannot be modified due to backwards compatibility.");
1041 static_assert(sizeof(DacpSyncBlockData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility.");
1042 static_assert(sizeof(DacpGetModuleAddress) == 0x8, "Dacp structs cannot be modified due to backwards compatibility.");
1043 static_assert(sizeof(DacpFrameData) == 0x8, "Dacp structs cannot be modified due to backwards compatibility.");
1044 static_assert(sizeof(DacpJitCodeHeapInfo) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1045 static_assert(sizeof(DacpExceptionObjectData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility.");
1047 #endif // _DACPRIVATE_H_