From 476dc1cb88a0dcedd891a0ef7a2e05d5c2f94f68 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Thu, 6 Jun 2019 12:12:55 -0700 Subject: [PATCH] Clear syncblock early when `VERIFY_HEAP && DEBUG` to prevent verification asserts. (#24992) Fixes:#24879 --- src/gc/gc.cpp | 11 +++++++++++ src/vm/object.cpp | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp index 100e2c2..35f46d4 100644 --- a/src/gc/gc.cpp +++ b/src/gc/gc.cpp @@ -12341,6 +12341,17 @@ found_fit: } #endif //FEATURE_LOH_COMPACTION +#if defined (VERIFY_HEAP) && defined (_DEBUG) + // we are responsible for cleaning the syncblock and we will do it later + // as a part of cleanup routine and when not holding the heap lock. + // However, once we move "allocated" forward and if another thread initiate verification of + // the previous object, it may consider the syncblock in the "next" eligible for validation. + // (see also: object.cpp/Object::ValidateInner) + // Make sure it will see cleaned up state to prevent triggering occasional verification failures. + // And make sure the write happens before updating "allocated" + VolatileStore(((void**)allocated - 1), (void*)0); //clear the sync block +#endif //VERIFY_HEAP && _DEBUG + dprintf (3, ("found fit at end of seg: %Ix", old_alloc)); uint8_t* old_alloc; diff --git a/src/vm/object.cpp b/src/vm/object.cpp index f0de65b..728e9d7 100644 --- a/src/vm/object.cpp +++ b/src/vm/object.cpp @@ -649,6 +649,10 @@ VOID Object::ValidateInner(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncB if ((nextObj != NULL) && (nextObj->GetGCSafeMethodTable() != g_pFreeObjectMethodTable)) { + // we need a read barrier here - to make sure we read the object header _after_ + // reading data that tells us that the object is eligible for verification + // (also see: gc.cpp/a_fit_segment_end_p) + VOLATILE_MEMORY_BARRIER(); CHECK_AND_TEAR_DOWN(nextObj->GetHeader()->Validate(FALSE)); } } -- 2.7.4