Revert "Remove workaround for null klass during marking phase"
This reverts commit 6408e9703d489fe35748b1b0887f974992f8eebb.
Reason for revert: The issue has not been fixed yet (b/232091270)
Bug: 232091270
Test: manual
Change-Id: I8b9e579fd6718e92e53f627bffff9eb3f2b0eca1
Merged-In: I8b9e579fd6718e92e53f627bffff9eb3f2b0eca1
(cherry picked from commit ad7963baa715a6638713da338e1def4f32e4a77b)
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index 6cbf178..0de62fe 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -1080,7 +1080,35 @@
REQUIRES_SHARED(Locks::heap_bitmap_lock_) {
DCHECK_EQ(collector_->RegionSpace()->RegionIdxForRef(obj), obj_region_idx_);
DCHECK(kHandleInterRegionRefs || collector_->immune_spaces_.ContainsObject(obj));
- CheckReference(obj->GetFieldObject<mirror::Object, kVerifyNone, kWithoutReadBarrier>(offset));
+ mirror::Object* ref =
+ obj->GetFieldObject<mirror::Object, kVerifyNone, kWithoutReadBarrier>(offset);
+ // TODO(lokeshgidra): Remove the following condition once b/173676071 is fixed.
+ if (UNLIKELY(ref == nullptr && offset == mirror::Object::ClassOffset())) {
+ // It has been verified as a race condition (see b/173676071)! After a small
+ // wait when we reload the class pointer, it turns out to be a valid class
+ // object. So as a workaround, we can continue execution and log an error
+ // that this happened.
+ for (size_t i = 0; i < 1000; i++) {
+ // Wait for 1ms at a time. Don't wait for more than 1 second in total.
+ usleep(1000);
+ ref = obj->GetClass<kVerifyNone, kWithoutReadBarrier>();
+ if (ref != nullptr) {
+ LOG(ERROR) << "klass pointer for obj: "
+ << obj << " (" << mirror::Object::PrettyTypeOf(obj)
+ << ") found to be null first. Reloading after a small wait fetched klass: "
+ << ref << " (" << mirror::Object::PrettyTypeOf(ref) << ")";
+ break;
+ }
+ }
+
+ if (UNLIKELY(ref == nullptr)) {
+ // It must be heap corruption. Remove memory protection and dump data.
+ collector_->region_space_->Unprotect();
+ LOG(FATAL_WITHOUT_ABORT) << "klass pointer for ref: " << obj << " found to be null.";
+ collector_->heap_->GetVerification()->LogHeapCorruption(obj, offset, ref, /* fatal */ true);
+ }
+ }
+ CheckReference(ref);
}
void operator()(ObjPtr<mirror::Class> klass, ObjPtr<mirror::Reference> ref) const