diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2018-10-05 02:11:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-05 02:11:35 +0200 |
commit | 957eceed83cf635fc3146eadc448bf50efde5431 (patch) | |
tree | ebe5d0ca5a3d0cb107ae46cb765be39a27cf1c04 /src/ToolBox | |
parent | 030e0af89bb897554acef575075c69aaf5176268 (diff) | |
download | coreclr-957eceed83cf635fc3146eadc448bf50efde5431.tar.gz coreclr-957eceed83cf635fc3146eadc448bf50efde5431.tar.bz2 coreclr-957eceed83cf635fc3146eadc448bf50efde5431.zip |
Add printing of LoaderAllocator to MethodTable in SOS (#20255)
This change adds printing of LoaderAllocator to MethodTable dump in SOS
for collectible types.
Diffstat (limited to 'src/ToolBox')
-rw-r--r-- | src/ToolBox/SOS/Strike/gcroot.cpp | 80 | ||||
-rw-r--r-- | src/ToolBox/SOS/Strike/sos.cpp | 1 | ||||
-rw-r--r-- | src/ToolBox/SOS/Strike/sos.h | 5 | ||||
-rw-r--r-- | src/ToolBox/SOS/Strike/strike.cpp | 12 | ||||
-rw-r--r-- | src/ToolBox/SOS/Strike/util.h | 1 |
5 files changed, 73 insertions, 26 deletions
diff --git a/src/ToolBox/SOS/Strike/gcroot.cpp b/src/ToolBox/SOS/Strike/gcroot.cpp index cd13719094..1417748f28 100644 --- a/src/ToolBox/SOS/Strike/gcroot.cpp +++ b/src/ToolBox/SOS/Strike/gcroot.cpp @@ -1972,6 +1972,22 @@ void HeapTraverser::PrintObjectHead(size_t objAddr,size_t typeID,size_t Size) } } +void HeapTraverser::PrintLoaderAllocator(size_t memberValue) +{ + if (m_format == FORMAT_XML) + { + fprintf(m_file, + " <loaderallocator address=\"0x%p\"/>\n", + (PBYTE)memberValue); + } + else if (m_format == FORMAT_CLRPROFILER) + { + fprintf(m_file, + " 0x%p", + (PBYTE)memberValue); + } +} + void HeapTraverser::PrintObjectMember(size_t memberValue, bool dependentHandle) { if (m_format==FORMAT_XML) @@ -2172,43 +2188,55 @@ void HeapTraverser::PrintRefs(size_t obj, size_t methodTable, size_t size) MethodTableInfo* info = g_special_mtCache.Lookup((DWORD_PTR)methodTable); _ASSERTE(info->IsInitialized()); // This is the second pass, so we should be initialized - if (!info->bContainsPointers) + if (!info->bContainsPointers && !info->bCollectible) return; - // Fetch the GCInfo from the other process - CGCDesc *map = info->GCInfo; - if (map == NULL) + if (info->bContainsPointers) { - INT_PTR nEntries; - move_xp (nEntries, dwAddr-sizeof(PVOID)); - bool arrayOfVC = false; - if (nEntries<0) - { - arrayOfVC = true; - nEntries = -nEntries; - } - - size_t nSlots = 1+nEntries*sizeof(CGCDescSeries)/sizeof(DWORD_PTR); - info->GCInfoBuffer = new DWORD_PTR[nSlots]; - if (info->GCInfoBuffer == NULL) + // Fetch the GCInfo from the other process + CGCDesc *map = info->GCInfo; + if (map == NULL) { - ReportOOM(); - return; - } + INT_PTR nEntries; + move_xp (nEntries, dwAddr-sizeof(PVOID)); + bool arrayOfVC = false; + if (nEntries<0) + { + arrayOfVC = true; + nEntries = -nEntries; + } - if (FAILED(rvCache->Read(TO_CDADDR(dwAddr - nSlots*sizeof(DWORD_PTR)), - info->GCInfoBuffer, (ULONG) (nSlots*sizeof(DWORD_PTR)), NULL))) - return; - - map = info->GCInfo = (CGCDesc*)(info->GCInfoBuffer+nSlots); - info->ArrayOfVC = arrayOfVC; + size_t nSlots = 1+nEntries*sizeof(CGCDescSeries)/sizeof(DWORD_PTR); + info->GCInfoBuffer = new DWORD_PTR[nSlots]; + if (info->GCInfoBuffer == NULL) + { + ReportOOM(); + return; + } + + if (FAILED(rvCache->Read(TO_CDADDR(dwAddr - nSlots*sizeof(DWORD_PTR)), + info->GCInfoBuffer, (ULONG) (nSlots*sizeof(DWORD_PTR)), NULL))) + return; + + map = info->GCInfo = (CGCDesc*)(info->GCInfoBuffer+nSlots); + info->ArrayOfVC = arrayOfVC; + } } mCache.EnsureRangeInCache((TADDR)obj, (unsigned int)size); for (sos::RefIterator itr(obj, info->GCInfo, info->ArrayOfVC, &mCache); itr; ++itr) { if (*itr && (!m_verify || sos::IsObject(*itr))) - PrintObjectMember(*itr, false); + { + if (itr.IsLoaderAllocator()) + { + PrintLoaderAllocator(*itr); + } + else + { + PrintObjectMember(*itr, false); + } + } } std::unordered_map<TADDR, std::list<TADDR>>::iterator itr = mDependentHandleMap.find((TADDR)obj); diff --git a/src/ToolBox/SOS/Strike/sos.cpp b/src/ToolBox/SOS/Strike/sos.cpp index 5ff77a905a..bf84e1d8af 100644 --- a/src/ToolBox/SOS/Strike/sos.cpp +++ b/src/ToolBox/SOS/Strike/sos.cpp @@ -562,6 +562,7 @@ namespace sos // There are no object references, but there is still a reference for // collectible types - the LoaderAllocator for GC mCurr = mLoaderAllocatorObjectHandle; + mDone = false; } } } diff --git a/src/ToolBox/SOS/Strike/sos.h b/src/ToolBox/SOS/Strike/sos.h index ff5b53a9c7..80608dd371 100644 --- a/src/ToolBox/SOS/Strike/sos.h +++ b/src/ToolBox/SOS/Strike/sos.h @@ -475,6 +475,11 @@ namespace sos { return (void*)!mDone; } + + bool IsLoaderAllocator() const + { + return mLoaderAllocatorObjectHandle == mCurr; + } private: void Init(); diff --git a/src/ToolBox/SOS/Strike/strike.cpp b/src/ToolBox/SOS/Strike/strike.cpp index cd3b9f299c..70e60312f2 100644 --- a/src/ToolBox/SOS/Strike/strike.cpp +++ b/src/ToolBox/SOS/Strike/strike.cpp @@ -1338,6 +1338,9 @@ DECLARE_API(DumpMT) return Status; } + DacpMethodTableCollectibleData vMethTableCollectible; + vMethTableCollectible.Request(g_sos, TO_CDADDR(dwStartAddr)); + table.WriteRow("EEClass:", EEClassPtr(vMethTable.Class)); table.WriteRow("Module:", ModulePtr(vMethTable.Module)); @@ -1350,6 +1353,15 @@ DECLARE_API(DumpMT) table.WriteRow("mdToken:", Pointer(vMethTable.cl)); table.WriteRow("File:", fileName[0] ? fileName : W("Unknown Module")); + if (vMethTableCollectible.LoaderAllocatorObjectHandle != NULL) + { + TADDR loaderAllocator; + if (SUCCEEDED(MOVE(loaderAllocator, vMethTableCollectible.LoaderAllocatorObjectHandle))) + { + table.WriteRow("LoaderAllocator:", ObjectPtr(loaderAllocator)); + } + } + table.WriteRow("BaseSize:", PrefixHex(vMethTable.BaseSize)); table.WriteRow("ComponentSize:", PrefixHex(vMethTable.ComponentSize)); table.WriteRow("Slots in VTable:", Decimal(vMethTable.wNumMethods)); diff --git a/src/ToolBox/SOS/Strike/util.h b/src/ToolBox/SOS/Strike/util.h index ebad2e49ff..1a4cd129ae 100644 --- a/src/ToolBox/SOS/Strike/util.h +++ b/src/ToolBox/SOS/Strike/util.h @@ -2831,6 +2831,7 @@ private: void PrintObjectHead(size_t objAddr,size_t typeID,size_t Size); void PrintObjectMember(size_t memberValue, bool dependentHandle); + void PrintLoaderAllocator(size_t memberValue); void PrintObjectTail(); void PrintRootHead(); |