Skip to content

Commit a74f248

Browse files
authored
Fix asserts (#3074)
***NO_CI***
1 parent bd4d280 commit a74f248

File tree

3 files changed

+121
-18
lines changed

3 files changed

+121
-18
lines changed

src/CLR/Core/CLR_RT_HeapCluster.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,50 +336,90 @@ void CLR_RT_HeapCluster::ValidateBlock(CLR_RT_HeapBlock *ptr)
336336
{
337337
if (ptr < m_payloadStart || ptr >= m_payloadEnd)
338338
{
339+
#ifdef _WIN64
340+
CLR_Debug::Printf(
341+
"Block beyond cluster limits: 0x%016" PRIxPTR " [0x%016" PRIxPTR " : 0x%016" PRIxPTR "-0x%016" PRIxPTR
342+
"]\r\n",
343+
(uintptr_t)ptr,
344+
(uintptr_t)this,
345+
(uintptr_t)m_payloadStart,
346+
(uintptr_t)m_payloadEnd);
347+
348+
#else
349+
339350
CLR_Debug::Printf(
340351
"Block beyond cluster limits: %08x [%08x : %08x-%08x]\r\n",
341352
(size_t)ptr,
342353
(size_t)this,
343354
(size_t)m_payloadStart,
344355
(size_t)m_payloadEnd);
356+
#endif
345357

346358
break;
347359
}
348360

349361
if (ptr->DataType() >= DATATYPE_FIRST_INVALID)
350362
{
363+
#ifdef _WIN64
364+
CLR_Debug::Printf(
365+
"Bad Block Type: 0x%016" PRIxPTR " %02x [0x%016" PRIxPTR " : 0x%016" PRIxPTR "-0x%016" PRIxPTR "]\r\n",
366+
(uintptr_t)ptr,
367+
ptr->DataType(),
368+
(uintptr_t)this,
369+
(uintptr_t)m_payloadStart,
370+
(uintptr_t)m_payloadEnd);
371+
#else
351372
CLR_Debug::Printf(
352373
"Bad Block Type: %08x %02x [%08x : %08x-%08x]\r\n",
353374
(size_t)ptr,
354375
ptr->DataType(),
355376
(size_t)this,
356377
(size_t)m_payloadStart,
357378
(size_t)m_payloadEnd);
379+
#endif
358380

359381
break;
360382
}
361383

362384
if (ptr->DataSize() == 0)
363385
{
386+
#ifdef _WIN64
387+
CLR_Debug::Printf(
388+
"Bad Block null-size: 0x%016" PRIxPTR " [0x%016" PRIxPTR " : 0x%016" PRIxPTR "-0x%016" PRIxPTR "]\r\n",
389+
(uintptr_t)ptr,
390+
(uintptr_t)this,
391+
(uintptr_t)m_payloadStart,
392+
(uintptr_t)m_payloadEnd);
393+
#else
364394
CLR_Debug::Printf(
365395
"Bad Block null-size: %08x [%08x : %08x-%08x]\r\n",
366396
(size_t)ptr,
367397
(size_t)this,
368398
(size_t)m_payloadStart,
369399
(size_t)m_payloadEnd);
400+
#endif
370401

371402
break;
372403
}
373404

374405
if (ptr + ptr->DataSize() > m_payloadEnd)
375406
{
407+
#ifdef _WIN64
408+
CLR_Debug::Printf(
409+
"Bad Block size: 0x%016" PRIxPTR " [0x%016" PRIxPTR " : 0x%016" PRIxPTR "-0x%016" PRIxPTR "]\r\n",
410+
(uintptr_t)ptr,
411+
(uintptr_t)this,
412+
(uintptr_t)m_payloadStart,
413+
(uintptr_t)m_payloadEnd);
414+
#else
376415
CLR_Debug::Printf(
377416
"Bad Block size: %d %08x [%08x : %08x-%08x]\r\n",
378417
ptr->DataSize(),
379418
(size_t)ptr,
380419
(size_t)this,
381420
(size_t)m_payloadStart,
382421
(size_t)m_payloadEnd);
422+
#endif
383423

384424
break;
385425
}

src/CLR/Core/GarbageCollector_Compaction.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//
1+
//
22
// Copyright (c) .NET Foundation and Contributors
33
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
44
// See LICENSE file in the project root for full license information.
@@ -258,11 +258,11 @@ void CLR_RT_GarbageCollector::Heap_Compact()
258258

259259
#ifdef DEBUG
260260

261-
_ASSERTE(relocCurrent->m_destination >= (CLR_UINT8 *)g_CLR_RT_ExecutionEngine.m_heap.FirstNode());
262-
_ASSERTE(relocCurrent->m_destination < (CLR_UINT8 *)g_CLR_RT_ExecutionEngine.m_heap.LastNode());
263-
_ASSERTE(relocCurrent->m_start >= (CLR_UINT8 *)g_CLR_RT_ExecutionEngine.m_heap.FirstNode());
264-
_ASSERTE(relocCurrent->m_start < (CLR_UINT8 *)g_CLR_RT_ExecutionEngine.m_heap.LastNode());
265-
_ASSERTE(moveBytes <= (move * sizeof(CLR_RT_HeapBlock)));
261+
_ASSERTE(relocCurrent->m_destination >= (CLR_UINT8 *)freeRegion_hc->m_payloadStart);
262+
_ASSERTE(relocCurrent->m_destination < (CLR_UINT8 *)freeRegion_hc->m_payloadEnd);
263+
_ASSERTE(relocCurrent->m_start >= (CLR_UINT8 *)freeRegion_hc->m_payloadStart);
264+
_ASSERTE(relocCurrent->m_start < (CLR_UINT8 *)freeRegion_hc->m_payloadEnd);
265+
_ASSERTE(moveBytes == (move * sizeof(CLR_RT_HeapBlock)));
266266

267267
#endif
268268

@@ -472,19 +472,12 @@ void CLR_RT_GarbageCollector::Heap_Relocate_Pass(RelocateFtn ftn)
472472
NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster, hc, g_CLR_RT_ExecutionEngine.m_heap)
473473
{
474474
CLR_RT_HeapBlock_Node *ptr = hc->m_payloadStart;
475-
CLR_RT_HeapBlock_Node *end = hc->m_payloadEnd;
476-
477-
// check pointers
478-
_ASSERTE(ptr >= (void *)s_CLR_RT_Heap.m_location);
479-
_ASSERTE(ptr < (void *)(s_CLR_RT_Heap.m_location + s_CLR_RT_Heap.m_size));
480-
_ASSERTE(end >= (void *)s_CLR_RT_Heap.m_location);
481-
_ASSERTE(end <= (void *)(s_CLR_RT_Heap.m_location + s_CLR_RT_Heap.m_size));
475+
CLR_RT_HeapBlock_Node const *end = hc->m_payloadEnd;
482476

483477
while (ptr < end)
484478
{
485479
// check pointer
486-
_ASSERTE(ptr >= (void *)s_CLR_RT_Heap.m_location);
487-
_ASSERTE(ptr < (void *)(s_CLR_RT_Heap.m_location + s_CLR_RT_Heap.m_size));
480+
_ASSERTE(ptr >= hc->m_payloadStart && ptr <= hc->m_payloadEnd);
488481

489482
CLR_RT_HEAPBLOCK_RELOCATE(ptr);
490483

@@ -544,7 +537,16 @@ void CLR_RT_GarbageCollector::Heap_Relocate(void **ref)
544537
#if defined(NANOCLR_TRACE_MEMORY_STATS)
545538
if (s_CLR_RT_fTrace_MemoryStats >= c_CLR_RT_Trace_Verbose)
546539
{
547-
CLR_Debug::Printf("\r\nGC: Relocating Heap\r\n");
540+
if (dst == nullptr)
541+
{
542+
// nothing to do here
543+
CLR_Debug::Printf("\r\nGC: Skipping relocation as referenced object is null.\r\n");
544+
return;
545+
}
546+
else
547+
{
548+
CLR_Debug::Printf("\r\nGC: Relocating Heap\r\n");
549+
}
548550
}
549551
#endif
550552

@@ -570,8 +572,6 @@ void CLR_RT_GarbageCollector::Heap_Relocate(void **ref)
570572
else
571573
{
572574
destinationAddress = (void *)(dst + relocCurrent.m_offset);
573-
_ASSERTE(destinationAddress >= (void *)s_CLR_RT_Heap.m_location);
574-
_ASSERTE(destinationAddress < (void *)(s_CLR_RT_Heap.m_location + s_CLR_RT_Heap.m_size));
575575

576576
*ref = destinationAddress;
577577

src/CLR/Core/GarbageCollector_Info.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,71 @@ void CLR_RT_GarbageCollector::ValidateCluster(CLR_RT_HeapCluster *hc)
101101

102102
while (ptr < end)
103103
{
104+
// Validate the block and check for memory corruption
104105
hc->ValidateBlock(ptr);
105106

107+
#ifndef BUILD_RTM
108+
109+
// Perform boundary checks
110+
if (ptr + ptr->DataSize() > end)
111+
{
112+
113+
#ifdef _WIN64
114+
CLR_Debug::Printf("Block exceeds cluster boundary: 0x%016" PRIxPTR "\r\n", (uintptr_t)ptr);
115+
#else
116+
CLR_Debug::Printf("Block exceeds cluster boundary: %08x\r\n", ptr);
117+
#endif
118+
119+
NANOCLR_DEBUG_STOP();
120+
}
121+
122+
// Check for overlapping blocks, if this is not a class or value type
123+
// First the next block
124+
CLR_RT_HeapBlock_Node const *nextPtr = ptr->Next();
125+
if ((ptr->DataType() != DATATYPE_VALUETYPE && ptr->DataType() != DATATYPE_CLASS) && nextPtr)
126+
{
127+
// is the next pointer before or after the current block?
128+
if (nextPtr < ptr)
129+
{
130+
// nextPtr is before the current block
131+
if (nextPtr + nextPtr->DataSize() > ptr)
132+
{
133+
#ifdef _WIN64
134+
CLR_Debug::Printf(
135+
"Overlapping blocks detected. Next block of 0x%016" PRIxPTR " is overlapping it.\r\n",
136+
(uintptr_t)ptr);
137+
#else
138+
CLR_Debug::Printf("Overlapping blocks detected: Next block of %08x is overlapping it.\r\n", ptr);
139+
#endif
140+
}
141+
}
142+
}
143+
144+
// now the previous block
145+
CLR_RT_HeapBlock_Node const *prevPtr = ptr->Prev();
146+
if ((ptr->DataType() != DATATYPE_VALUETYPE && ptr->DataType() != DATATYPE_CLASS) && prevPtr)
147+
{
148+
// is the previous pointer before or after the current block?
149+
if (prevPtr < ptr)
150+
{
151+
// previousPtr is before the current block
152+
if (prevPtr + prevPtr->DataSize() > ptr)
153+
{
154+
#ifdef _WIN64
155+
CLR_Debug::Printf(
156+
"Overlapping blocks detected: Previous block of 0x%016" PRIxPTR " is overlapping it.\r\n",
157+
(uintptr_t)ptr);
158+
#else
159+
CLR_Debug::Printf(
160+
"Overlapping blocks detected: Previous block of %08x is overlapping it.\r\n",
161+
ptr);
162+
#endif
163+
}
164+
}
165+
}
166+
167+
#endif // !BUILD_RTM
168+
106169
ptr += ptr->DataSize();
107170
}
108171
}

0 commit comments

Comments
 (0)