Skip to content

Commit 9616b57

Browse files
authored
NextObj fix (#71113)
this is to fix #70231. for regions we could run into this situation - object is the last object before heap_segment_allocated (hs) T0 calls NextObj, gets next obj which starts at heap_segment_allocated (hs) T1 changes ephemeral_heap_segment to hs T0 does these comparisons (nextobj >= heap_segment_allocated(hs) && hs != hp->ephemeral_heap_segment) || (nextobj >= hp->alloc_allocated)) both still false because alloc_allocated hasn't been changed just yet (and the old alloc_allocated is larger than nextobj) T0 validates next obj, concludes its m_alignpad is not 0, asserts T1 forms an allocation context starting at heap_segment_allocated, clears memory so by the time the dump is taken, m_alignpad is already cleared (actually we clear it in a_fit_segment_end) I'm fixing this by saving the ephemeral_heap_segment and alloc_allocated and bail if nextobj is not on the saved eph seg or if those 2 saved values are no long in sync.
1 parent f4cf69e commit 9616b57

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

src/coreclr/gc/gc.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44526,9 +44526,25 @@ Object * GCHeap::NextObj (Object * object)
4452644526
return NULL;
4452744527
}
4452844528

44529-
if ((nextobj < heap_segment_mem(hs)) ||
44530-
(nextobj >= heap_segment_allocated(hs) && hs != hp->ephemeral_heap_segment) ||
44531-
(nextobj >= hp->alloc_allocated))
44529+
if (nextobj < heap_segment_mem (hs))
44530+
{
44531+
return NULL;
44532+
}
44533+
44534+
uint8_t* saved_alloc_allocated = hp->alloc_allocated;
44535+
heap_segment* saved_ephemeral_heap_segment = hp->ephemeral_heap_segment;
44536+
44537+
// We still want to verify nextobj that lands between heap_segment_allocated and alloc_allocated
44538+
// on the ephemeral segment. In regions these 2 could be changed by another thread so we need
44539+
// to make sure they are still in sync by the time we check. If they are not in sync, we just
44540+
// bail which means we don't validate the next object during that small window and that's fine.
44541+
//
44542+
// We also miss validating nextobj if it's in the segment that just turned into the new ephemeral
44543+
// segment since we saved which is also a very small window and again that's fine.
44544+
if ((nextobj >= heap_segment_allocated (hs)) &&
44545+
((hs != saved_ephemeral_heap_segment) ||
44546+
!in_range_for_segment(saved_alloc_allocated, saved_ephemeral_heap_segment) ||
44547+
(nextobj >= saved_alloc_allocated)))
4453244548
{
4453344549
return NULL;
4453444550
}

0 commit comments

Comments
 (0)