Skip to content

Commit d8cc63f

Browse files
author
Mike McLaughlin
authored
Add faster DAC EnumMemoryRegion option with less memory usage (#74300) (#74464)
Issue: #72148 Instead of drilling down into all the individual MT/MD/EEClass, etc. data structures, add the LoaderAllocator/LoaderHeaps regions directly. Add new CLRDATA_ENUM_MEM_HEAP2 flag for the fast path. To reduce risk of incomplete core dumps this is enabled by the COMPlus_EnableFastHeapDumps env var. This env var is only looked at by the Linux/MacOS createdump. It is currently ignored on Windows. The new HEAP2 flag is works when passed to the EnumMemoryRegions API on Windows but createdump can't set it because MiniDumpWriteDump in dbghelp.dll loads/calls the DAC API. Fix MacOS dlopen error message
1 parent b211223 commit d8cc63f

23 files changed

+162
-108
lines changed

src/coreclr/debug/createdump/crashinfo.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
#include "createdump.h"
5+
#include <clrconfignocache.h>
56

67
// This is for the PAL_VirtualUnwindOutOfProc read memory adapter.
78
CrashInfo* g_crashInfo;
@@ -328,24 +329,34 @@ CrashInfo::EnumerateMemoryRegionsWithDAC(MINIDUMP_TYPE minidumpType)
328329
{
329330
TRACE("EnumerateMemoryRegionsWithDAC: Memory enumeration STARTED (%d %d)\n", m_enumMemoryPagesAdded, m_dataTargetPagesAdded);
330331

331-
// Since on both Linux and MacOS all the RW regions will be added for heap
332-
// dumps by createdump, the only thing differentiating a MiniDumpNormal and
333-
// a MiniDumpWithPrivateReadWriteMemory is that the later uses the EnumMemory
334-
// APIs. This is kind of expensive on larger applications (4 minutes, or even
335-
// more), and this should already be in RW pages. Change the dump type to the
336-
// faster normal one. This one already ensures necessary DAC globals, etc.
337-
// without the costly assembly, module, class, type runtime data structures
338-
// enumeration.
332+
// Since on MacOS all the RW regions will be added for heap dumps by createdump, the
333+
// only thing differentiating a MiniDumpNormal and a MiniDumpWithPrivateReadWriteMemory
334+
// is that the later uses the EnumMemoryRegions APIs. This is kind of expensive on larger
335+
// applications (4 minutes, or even more), and this should already be in RW pages. Change
336+
// the dump type to the faster normal one. This one already ensures necessary DAC globals,
337+
// etc. without the costly assembly, module, class, type runtime data structures enumeration.
338+
CLRDataEnumMemoryFlags flags = CLRDATA_ENUM_MEM_DEFAULT;
339339
if (minidumpType & MiniDumpWithPrivateReadWriteMemory)
340340
{
341-
char* fastHeapDumps = getenv("COMPlus_DbgEnableFastHeapDumps");
342-
if (fastHeapDumps != nullptr && strcmp(fastHeapDumps, "1") == 0)
341+
// This is the old fast heap env var for backwards compatibility for VS4Mac.
342+
CLRConfigNoCache fastHeapDumps = CLRConfigNoCache::Get("DbgEnableFastHeapDumps", /*noprefix*/ false, &getenv);
343+
DWORD val = 0;
344+
if (fastHeapDumps.IsSet() && fastHeapDumps.TryAsInteger(10, val) && val == 1)
343345
{
344346
minidumpType = MiniDumpNormal;
345347
}
348+
// This the new variable that also skips the expensive (in both time and memory usage)
349+
// enumeration of the low level data structures and adds all the loader allocator heaps
350+
// instead. The above original env var didn't generate a complete enough heap dump on
351+
// Linux and this new one does.
352+
fastHeapDumps = CLRConfigNoCache::Get("EnableFastHeapDumps", /*noprefix*/ false, &getenv);
353+
if (fastHeapDumps.IsSet() && fastHeapDumps.TryAsInteger(10, val) && val == 1)
354+
{
355+
flags = CLRDATA_ENUM_MEM_HEAP2;
356+
}
346357
}
347358
// Calls CrashInfo::EnumMemoryRegion for each memory region found by the DAC
348-
HRESULT hr = m_pClrDataEnumRegions->EnumMemoryRegions(this, minidumpType, CLRDATA_ENUM_MEM_DEFAULT);
359+
HRESULT hr = m_pClrDataEnumRegions->EnumMemoryRegions(this, minidumpType, flags);
349360
if (FAILED(hr))
350361
{
351362
printf_error("EnumMemoryRegions FAILED %s (%08x)\n", GetHResultString(hr), hr);

src/coreclr/debug/createdump/crashinfomac.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ ModuleInfo::LoadModule()
487487
}
488488
else
489489
{
490-
TRACE("LoadModule: dlopen(%s) FAILED %d %s\n", m_moduleName.c_str(), errno, strerror(errno));
490+
TRACE("LoadModule: dlopen(%s) FAILED %s\n", m_moduleName.c_str(), dlerror());
491491
}
492492
}
493493
}

src/coreclr/debug/daccess/daccess.cpp

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6246,24 +6246,15 @@ bool ClrDataAccess::ReportMem(TADDR addr, TSIZE_T size, bool fExpectSuccess /*=
62466246
{
62476247
if (!IsFullyReadable(addr, size))
62486248
{
6249-
if (!fExpectSuccess)
6249+
if (fExpectSuccess)
62506250
{
6251-
// We know the read might fail (eg. we're trying to find mapped pages in
6252-
// a module image), so just skip this block silently.
6253-
// Note that the EnumMemoryRegion callback won't necessarily do anything if any part of
6254-
// the region is unreadable, and so there is no point in calling it. For cases where we expect
6255-
// the read might fail, but we want to report any partial blocks, we have to break up the region
6256-
// into pages and try reporting each page anyway
6257-
return true;
6251+
// We're reporting bogus memory, so the target must be corrupt (or there is a issue). We should abort
6252+
// reporting and continue with the next data structure (where the exception is caught),
6253+
// just like we would for a DAC read error (otherwise we might do something stupid
6254+
// like get into an infinite loop, or otherwise waste time with corrupt data).
6255+
TARGET_CONSISTENCY_CHECK(false, "Found unreadable memory while reporting memory regions for dump gathering");
6256+
return false;
62586257
}
6259-
6260-
// We're reporting bogus memory, so the target must be corrupt (or there is a issue). We should abort
6261-
// reporting and continue with the next data structure (where the exception is caught),
6262-
// just like we would for a DAC read error (otherwise we might do something stupid
6263-
// like get into an infinite loop, or otherwise waste time with corrupt data).
6264-
6265-
TARGET_CONSISTENCY_CHECK(false, "Found unreadable memory while reporting memory regions for dump gathering");
6266-
return false;
62676258
}
62686259
}
62696260

@@ -6275,9 +6266,7 @@ bool ClrDataAccess::ReportMem(TADDR addr, TSIZE_T size, bool fExpectSuccess /*=
62756266
// data structure at all. Hopefully experience will help guide this going forward.
62766267
// @dbgtodo : Extend dump-gathering API to allow a dump-log to be included.
62776268
const TSIZE_T kMaxMiniDumpRegion = 4*1024*1024 - 3; // 4MB-3
6278-
if( size > kMaxMiniDumpRegion
6279-
&& (m_enumMemFlags == CLRDATA_ENUM_MEM_MINI
6280-
|| m_enumMemFlags == CLRDATA_ENUM_MEM_TRIAGE))
6269+
if (size > kMaxMiniDumpRegion && (m_enumMemFlags == CLRDATA_ENUM_MEM_MINI || m_enumMemFlags == CLRDATA_ENUM_MEM_TRIAGE))
62816270
{
62826271
TARGET_CONSISTENCY_CHECK( false, "Dump target consistency failure - truncating minidump data structure");
62836272
size = kMaxMiniDumpRegion;

src/coreclr/debug/daccess/dacdbiimpl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3618,7 +3618,7 @@ void DacDbiInterfaceImpl::EnumerateMemRangesForLoaderAllocator(PTR_LoaderAllocat
36183618

36193619
// GetVirtualCallStubManager returns VirtualCallStubManager*, but it's really an address to target as
36203620
// pLoaderAllocator is DACized. Cast it so we don't try to to a Host to Target translation.
3621-
VirtualCallStubManager *pVcsMgr = PTR_VirtualCallStubManager(TO_TADDR(pLoaderAllocator->GetVirtualCallStubManager()));
3621+
VirtualCallStubManager *pVcsMgr = pLoaderAllocator->GetVirtualCallStubManager();
36223622
LOG((LF_CORDB, LL_INFO10000, "DDBII::EMRFLA: VirtualCallStubManager 0x%x\n", PTR_HOST_TO_TADDR(pVcsMgr)));
36233623
if (pVcsMgr)
36243624
{

src/coreclr/debug/daccess/dacimpl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,7 @@ class ClrDataAccess
13281328

13291329
HRESULT EnumMemCollectImages();
13301330
HRESULT EnumMemCLRStatic(CLRDataEnumMemoryFlags flags);
1331+
HRESULT EnumMemDumpJitManagerInfo(IN CLRDataEnumMemoryFlags flags);
13311332
HRESULT EnumMemCLRHeapCrticalStatic(CLRDataEnumMemoryFlags flags);
13321333
HRESULT EnumMemDumpModuleList(CLRDataEnumMemoryFlags flags);
13331334
HRESULT EnumMemDumpAppDomainInfo(CLRDataEnumMemoryFlags flags);

src/coreclr/debug/daccess/enummem.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,21 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags)
283283
return S_OK;
284284
}
285285

286+
HRESULT ClrDataAccess::EnumMemDumpJitManagerInfo(IN CLRDataEnumMemoryFlags flags)
287+
{
288+
SUPPORTS_DAC;
289+
290+
HRESULT status = S_OK;
291+
292+
if (flags == CLRDATA_ENUM_MEM_HEAP2)
293+
{
294+
EEJitManager* managerPtr = ExecutionManager::GetEEJitManager();
295+
managerPtr->EnumMemoryRegions(flags);
296+
}
297+
298+
return status;
299+
}
300+
286301
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
287302
//
288303
// This function reports memory that a heap dump need to debug CLR
@@ -325,6 +340,9 @@ HRESULT ClrDataAccess::EnumMemoryRegionsWorkerHeap(IN CLRDataEnumMemoryFlags fla
325340
// Dump AppDomain-specific info
326341
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( status = EnumMemDumpAppDomainInfo(flags); )
327342

343+
// Dump jit manager info
344+
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( status = EnumMemDumpJitManagerInfo(flags); )
345+
328346
// Dump the Debugger object data needed
329347
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pDebugger->EnumMemoryRegions(flags); )
330348

@@ -680,6 +698,11 @@ HRESULT ClrDataAccess::EnumMemDumpAppDomainInfo(CLRDataEnumMemoryFlags flags)
680698
{
681699
SUPPORTS_DAC;
682700

701+
if (flags == CLRDATA_ENUM_MEM_HEAP2)
702+
{
703+
SystemDomain::System()->GetLoaderAllocator()->EnumMemoryRegions(flags);
704+
}
705+
683706
AppDomainIterator adIter(FALSE);
684707
EX_TRY
685708
{
@@ -1853,7 +1876,7 @@ HRESULT ClrDataAccess::EnumMemoryRegionsWrapper(IN CLRDataEnumMemoryFlags flags)
18531876
// triage micro-dump
18541877
status = EnumMemoryRegionsWorkerMicroTriage(flags);
18551878
}
1856-
else if (flags == CLRDATA_ENUM_MEM_HEAP)
1879+
else if (flags == CLRDATA_ENUM_MEM_HEAP || flags == CLRDATA_ENUM_MEM_HEAP2)
18571880
{
18581881
status = EnumMemoryRegionsWorkerHeap(flags);
18591882
}
@@ -1946,7 +1969,15 @@ ClrDataAccess::EnumMemoryRegions(IN ICLRDataEnumMemoryRegionsCallback* callback,
19461969
if (miniDumpFlags & MiniDumpWithPrivateReadWriteMemory)
19471970
{
19481971
// heap dump
1949-
status = EnumMemoryRegionsWrapper(CLRDATA_ENUM_MEM_HEAP);
1972+
if (flags == CLRDATA_ENUM_MEM_HEAP2)
1973+
{
1974+
DacLogMessage("EnumMemoryRegions(CLRDATA_ENUM_MEM_HEAP2)\n");
1975+
}
1976+
else
1977+
{
1978+
flags = CLRDATA_ENUM_MEM_HEAP;
1979+
}
1980+
status = EnumMemoryRegionsWrapper(flags);
19501981
}
19511982
else if (miniDumpFlags & MiniDumpWithFullAuxiliaryState)
19521983
{

src/coreclr/debug/daccess/request.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3497,7 +3497,7 @@ ClrDataAccess::TraverseVirtCallStubHeap(CLRDATA_ADDRESS pAppDomain, VCSHeapType
34973497
SOSDacEnter();
34983498

34993499
BaseDomain* pBaseDomain = PTR_BaseDomain(TO_TADDR(pAppDomain));
3500-
VirtualCallStubManager *pVcsMgr = PTR_VirtualCallStubManager((TADDR)pBaseDomain->GetLoaderAllocator()->GetVirtualCallStubManager());
3500+
VirtualCallStubManager *pVcsMgr = pBaseDomain->GetLoaderAllocator()->GetVirtualCallStubManager();
35013501
if (!pVcsMgr)
35023502
{
35033503
hr = E_POINTER;

src/coreclr/debug/ee/debugger.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16596,22 +16596,23 @@ Debugger::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
1659616596
{
1659716597
DAC_ENUM_VTHIS();
1659816598
SUPPORTS_DAC;
16599-
_ASSERTE(m_rgHijackFunction != NULL);
1660016599

16601-
if ( flags != CLRDATA_ENUM_MEM_TRIAGE)
16600+
if (flags != CLRDATA_ENUM_MEM_TRIAGE)
1660216601
{
1660316602
if (m_pMethodInfos.IsValid())
1660416603
{
1660516604
m_pMethodInfos->EnumMemoryRegions(flags);
1660616605
}
1660716606

16608-
DacEnumMemoryRegion(dac_cast<TADDR>(m_pLazyData),
16609-
sizeof(DebuggerLazyInit));
16607+
DacEnumMemoryRegion(dac_cast<TADDR>(m_pLazyData), sizeof(DebuggerLazyInit));
1661016608
}
1661116609

1661216610
// Needed for stack walking from an initial native context. If the debugger can find the
1661316611
// on-disk image of clr.dll, then this is not necessary.
16614-
DacEnumMemoryRegion(dac_cast<TADDR>(m_rgHijackFunction), sizeof(MemoryRange)*kMaxHijackFunctions);
16612+
if (m_rgHijackFunction.IsValid())
16613+
{
16614+
DacEnumMemoryRegion(dac_cast<TADDR>(m_rgHijackFunction), sizeof(MemoryRange)*kMaxHijackFunctions);
16615+
}
1661516616
}
1661616617

1661716618

src/coreclr/debug/ee/functioninfo.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2456,9 +2456,7 @@ DebuggerMethodInfoEntry::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
24562456

24572457
// For a MiniDumpNormal, what is needed for modules is already enumerated elsewhere.
24582458
// Don't waste time doing it here an extra time. Also, this will add many MB extra into the dump.
2459-
if ((key.pModule.IsValid()) &&
2460-
CLRDATA_ENUM_MEM_MINI != flags
2461-
&& CLRDATA_ENUM_MEM_TRIAGE != flags)
2459+
if ((key.pModule.IsValid()) && CLRDATA_ENUM_MEM_MINI != flags && CLRDATA_ENUM_MEM_TRIAGE != flags && CLRDATA_ENUM_MEM_HEAP2 != flags)
24622460
{
24632461
key.pModule->EnumMemoryRegions(flags, true);
24642462
}
@@ -2476,7 +2474,7 @@ DebuggerMethodInfo::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
24762474
DAC_ENUM_DTHIS();
24772475
SUPPORTS_DAC;
24782476

2479-
if (flags != CLRDATA_ENUM_MEM_MINI && flags != CLRDATA_ENUM_MEM_TRIAGE)
2477+
if (flags != CLRDATA_ENUM_MEM_MINI && flags != CLRDATA_ENUM_MEM_TRIAGE && flags != CLRDATA_ENUM_MEM_HEAP2)
24802478
{
24812479
// Modules are enumerated already for minidumps, save the empty calls.
24822480
if (m_module.IsValid())
@@ -2505,7 +2503,7 @@ DebuggerJitInfo::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
25052503
m_methodInfo->EnumMemoryRegions(flags);
25062504
}
25072505

2508-
if (flags != CLRDATA_ENUM_MEM_MINI && flags != CLRDATA_ENUM_MEM_TRIAGE)
2506+
if (flags != CLRDATA_ENUM_MEM_MINI && flags != CLRDATA_ENUM_MEM_TRIAGE && flags != CLRDATA_ENUM_MEM_HEAP2)
25092507
{
25102508
if (m_nativeCodeVersion.GetMethodDesc().IsValid())
25112509
{

src/coreclr/inc/clrdata.idl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,12 @@ interface ICLRDataLoggingCallback : IUnknown
308308
typedef enum CLRDataEnumMemoryFlags
309309
{
310310
CLRDATA_ENUM_MEM_DEFAULT = 0x0,
311-
CLRDATA_ENUM_MEM_MINI = CLRDATA_ENUM_MEM_DEFAULT, // generating skinny mini-dump
312-
CLRDATA_ENUM_MEM_HEAP = 0x1, // generating heap dump
313-
CLRDATA_ENUM_MEM_TRIAGE = 0x2, // generating triage mini-dump
314-
311+
CLRDATA_ENUM_MEM_MINI = CLRDATA_ENUM_MEM_DEFAULT, // generating skinny mini-dump
312+
CLRDATA_ENUM_MEM_HEAP = 0x1, // generating heap dump
313+
CLRDATA_ENUM_MEM_TRIAGE = 0x2, // generating triage mini-dump
314+
/* Generate heap dumps faster with less memory usage than CLRDATA_ENUM_MEM_HEAP by adding
315+
the loader heaps instead of traversing all the individual runtime data structures. */
316+
CLRDATA_ENUM_MEM_HEAP2 = 0x3,
315317
/* More bits to be added here later */
316318
} CLRDataEnumMemoryFlags;
317319

src/coreclr/inc/daccess.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2466,7 +2466,7 @@ typedef DPTR(PTR_PCODE) PTR_PTR_PCODE;
24662466

24672467
// Helper macro for tracking EnumMemoryRegions progress.
24682468
#if 0
2469-
#define EMEM_OUT(args) DacWarning args
2469+
#define EMEM_OUT(args) DacLogMessage args
24702470
#else
24712471
#define EMEM_OUT(args)
24722472
#endif

src/coreclr/pal/prebuilt/inc/clrdata.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,8 @@ enum CLRDataEnumMemoryFlags
12991299
CLRDATA_ENUM_MEM_DEFAULT = 0,
13001300
CLRDATA_ENUM_MEM_MINI = CLRDATA_ENUM_MEM_DEFAULT,
13011301
CLRDATA_ENUM_MEM_HEAP = 0x1,
1302-
CLRDATA_ENUM_MEM_TRIAGE = 0x2
1302+
CLRDATA_ENUM_MEM_TRIAGE = 0x2,
1303+
CLRDATA_ENUM_MEM_HEAP2 = 0x3
13031304
} CLRDataEnumMemoryFlags;
13041305

13051306

src/coreclr/utilcode/loaderheap.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ RangeList::RangeListBlock::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
341341
// code:LoaderHeap::UnlockedReservePages adds a range for the entire reserved region, instead
342342
// of updating the RangeList when pages are committed. But in that case, the committed region of
343343
// memory will be enumerated by the LoaderHeap anyway, so it's OK if this fails
344+
EMEM_OUT(("MEM: RangeListBlock %p - %p\n", range->start, range->end));
344345
DacEnumMemoryRegion(range->start, size, false);
345346
}
346347
}
@@ -1933,8 +1934,6 @@ void UnlockedLoaderHeap::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
19331934
{
19341935
WRAPPER_NO_CONTRACT;
19351936

1936-
DAC_ENUM_DTHIS();
1937-
19381937
PTR_LoaderHeapBlock block = m_pFirstBlock;
19391938
while (block.IsValid())
19401939
{
@@ -1946,6 +1945,7 @@ void UnlockedLoaderHeap::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
19461945
// but it seems wasteful (eg. makes each AppDomain objects 32 bytes larger on x64).
19471946
TADDR addr = dac_cast<TADDR>(block->pVirtualAddress);
19481947
TSIZE_T size = block->dwVirtualSize;
1948+
EMEM_OUT(("MEM: UnlockedLoaderHeap %p - %p\n", addr, addr + size));
19491949
DacEnumMemoryRegion(addr, size, false);
19501950

19511951
block = block->pNext;

src/coreclr/vm/appdomain.cpp

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5086,42 +5086,28 @@ DomainLocalModule::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
50865086
}
50875087

50885088
void
5089-
BaseDomain::EnumMemoryRegions(CLRDataEnumMemoryFlags flags,
5090-
bool enumThis)
5091-
{
5092-
SUPPORTS_DAC;
5093-
if (enumThis)
5094-
{
5095-
// This is wrong. Don't do it.
5096-
// BaseDomain cannot be instantiated.
5097-
// The only thing this code can hope to accomplish is to potentially break
5098-
// memory enumeration walking through the derived class if we
5099-
// explicitly call the base class enum first.
5100-
// DAC_ENUM_VTHIS();
5101-
}
5102-
5103-
EMEM_OUT(("MEM: %p BaseDomain\n", dac_cast<TADDR>(this)));
5104-
}
5105-
5106-
void
5107-
AppDomain::EnumMemoryRegions(CLRDataEnumMemoryFlags flags,
5108-
bool enumThis)
5089+
AppDomain::EnumMemoryRegions(CLRDataEnumMemoryFlags flags, bool enumThis)
51095090
{
51105091
SUPPORTS_DAC;
51115092

51125093
if (enumThis)
51135094
{
51145095
//sizeof(AppDomain) == 0xeb0
51155096
DAC_ENUM_VTHIS();
5097+
EMEM_OUT(("MEM: %p AppDomain\n", dac_cast<TADDR>(this)));
51165098
}
5117-
BaseDomain::EnumMemoryRegions(flags, false);
51185099

51195100
// We don't need AppDomain name in triage dumps.
51205101
if (flags != CLRDATA_ENUM_MEM_TRIAGE)
51215102
{
51225103
m_friendlyName.EnumMemoryRegions(flags);
51235104
}
51245105

5106+
if (flags == CLRDATA_ENUM_MEM_HEAP2)
5107+
{
5108+
GetLoaderAllocator()->EnumMemoryRegions(flags);
5109+
}
5110+
51255111
m_Assemblies.EnumMemoryRegions(flags);
51265112
AssemblyIterator assem = IterateAssembliesEx((AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution));
51275113
CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly;
@@ -5133,16 +5119,19 @@ AppDomain::EnumMemoryRegions(CLRDataEnumMemoryFlags flags,
51335119
}
51345120

51355121
void
5136-
SystemDomain::EnumMemoryRegions(CLRDataEnumMemoryFlags flags,
5137-
bool enumThis)
5122+
SystemDomain::EnumMemoryRegions(CLRDataEnumMemoryFlags flags, bool enumThis)
51385123
{
51395124
SUPPORTS_DAC;
51405125
if (enumThis)
51415126
{
51425127
DAC_ENUM_VTHIS();
5128+
EMEM_OUT(("MEM: %p SystemAppomain\n", dac_cast<TADDR>(this)));
51435129
}
5144-
BaseDomain::EnumMemoryRegions(flags, false);
51455130

5131+
if (flags == CLRDATA_ENUM_MEM_HEAP2)
5132+
{
5133+
GetLoaderAllocator()->EnumMemoryRegions(flags);
5134+
}
51465135
if (m_pSystemPEAssembly.IsValid())
51475136
{
51485137
m_pSystemPEAssembly->EnumMemoryRegions(flags);

0 commit comments

Comments
 (0)