Clear syncblock early when `VERIFY_HEAP && DEBUG` to prevent verification asserts...
authorVladimir Sadov <vsadov@microsoft.com>
Thu, 6 Jun 2019 19:12:55 +0000 (12:12 -0700)
committerGitHub <noreply@github.com>
Thu, 6 Jun 2019 19:12:55 +0000 (12:12 -0700)
Fixes:#24879

src/gc/gc.cpp
src/vm/object.cpp

index 100e2c2..35f46d4 100644 (file)
@@ -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;
index f0de65b..728e9d7 100644 (file)
@@ -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));
             }
         }