Skip to content

Commit

Permalink
NextObj fix (#71113)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Maoni0 authored Jun 22, 2022
1 parent f4cf69e commit 9616b57
Showing 1 changed file with 19 additions and 3 deletions.
22 changes: 19 additions & 3 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44526,9 +44526,25 @@ Object * GCHeap::NextObj (Object * object)
return NULL;
}

if ((nextobj < heap_segment_mem(hs)) ||
(nextobj >= heap_segment_allocated(hs) && hs != hp->ephemeral_heap_segment) ||
(nextobj >= hp->alloc_allocated))
if (nextobj < heap_segment_mem (hs))
{
return NULL;
}

uint8_t* saved_alloc_allocated = hp->alloc_allocated;
heap_segment* saved_ephemeral_heap_segment = hp->ephemeral_heap_segment;

// We still want to verify nextobj that lands between heap_segment_allocated and alloc_allocated
// on the ephemeral segment. In regions these 2 could be changed by another thread so we need
// to make sure they are still in sync by the time we check. If they are not in sync, we just
// bail which means we don't validate the next object during that small window and that's fine.
//
// We also miss validating nextobj if it's in the segment that just turned into the new ephemeral
// segment since we saved which is also a very small window and again that's fine.
if ((nextobj >= heap_segment_allocated (hs)) &&
((hs != saved_ephemeral_heap_segment) ||
!in_range_for_segment(saved_alloc_allocated, saved_ephemeral_heap_segment) ||
(nextobj >= saved_alloc_allocated)))
{
return NULL;
}
Expand Down

0 comments on commit 9616b57

Please sign in to comment.