From c4c26926697000b6f84a7ddb5e95068632399b45 Mon Sep 17 00:00:00 2001 From: Peter Sollich Date: Thu, 28 Oct 2021 13:47:45 +0200 Subject: [PATCH 1/2] Fix bug where we reference the entry in the pinned plug queue with index 0 when there may be no pinned plugs at all, and thus the refenced entry would be invalid. --- src/coreclr/gc/gc.cpp | 19 ++++++++++++++++--- src/coreclr/gc/gcpriv.h | 2 ++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 221d2dc2be6316..c0248e2fdb53d1 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -2711,7 +2711,7 @@ alloc_list gc_heap::poh_alloc_list [NUM_POH_ALIST-1]; #ifdef DOUBLY_LINKED_FL // size we removed with no undo; only for recording purpose size_t gc_heap::gen2_removed_no_undo = 0; -size_t gc_heap::saved_pinned_plug_index = 0; +size_t gc_heap::saved_pinned_plug_index = INVALID_SAVED_PINNED_PLUG_INDEX; #endif //DOUBLY_LINKED_FL #ifdef FEATURE_EVENT_TRACE @@ -14138,7 +14138,20 @@ void gc_heap::adjust_limit (uint8_t* start, size_t limit_size, generation* gen) uint8_t* old_loc = generation_last_free_list_allocated (gen); // check if old_loc happens to be in a saved plug_and_gap with a pinned plug after it - uint8_t* saved_plug_and_gap = pinned_plug (pinned_plug_of (saved_pinned_plug_index)) - sizeof(plug_and_gap); + uint8_t* saved_plug_and_gap = nullptr; + if (saved_pinned_plug_index != INVALID_SAVED_PINNED_PLUG_INDEX) + { + saved_plug_and_gap = pinned_plug (pinned_plug_of (saved_pinned_plug_index)) - sizeof(plug_and_gap); + + dprintf (3333, ("[h%d] sppi: %Id mtos: %Id old_loc: %Ix pp: %Ix(%Id) offs: %Id", + heap_number, + saved_pinned_plug_index, + mark_stack_tos, + old_loc, + pinned_plug (pinned_plug_of (saved_pinned_plug_index)), + pinned_len (pinned_plug_of (saved_pinned_plug_index)), + old_loc - saved_plug_and_gap)); + } size_t offset = old_loc - saved_plug_and_gap; if (offset < sizeof(gap_reloc_pair)) { @@ -27783,7 +27796,7 @@ void gc_heap::plan_phase (int condemned_gen_number) #ifdef DOUBLY_LINKED_FL gen2_removed_no_undo = 0; - saved_pinned_plug_index = 0; + saved_pinned_plug_index = INVALID_SAVED_PINNED_PLUG_INDEX; #endif //DOUBLY_LINKED_FL while (1) diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h index 051dd993014906..a18edb52fd5de6 100644 --- a/src/coreclr/gc/gcpriv.h +++ b/src/coreclr/gc/gcpriv.h @@ -4528,6 +4528,8 @@ class gc_heap PER_HEAP size_t gen2_removed_no_undo; +#define INVALID_SAVED_PINNED_PLUG_INDEX (~0) + PER_HEAP size_t saved_pinned_plug_index; #endif //DOUBLY_LINKED_FL From e14464540561e7f055481fcfe5203a47e6c9651f Mon Sep 17 00:00:00 2001 From: Peter Sollich Date: Fri, 29 Oct 2021 10:52:19 +0200 Subject: [PATCH 2/2] Fix Linux GCC build issue. --- src/coreclr/gc/gcpriv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h index a18edb52fd5de6..200e8ae58bec9a 100644 --- a/src/coreclr/gc/gcpriv.h +++ b/src/coreclr/gc/gcpriv.h @@ -4528,7 +4528,7 @@ class gc_heap PER_HEAP size_t gen2_removed_no_undo; -#define INVALID_SAVED_PINNED_PLUG_INDEX (~0) +#define INVALID_SAVED_PINNED_PLUG_INDEX ((size_t)~0) PER_HEAP size_t saved_pinned_plug_index;