From 1e1a47204984e3b72c4a753a2beb704350f38373 Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi Date: Fri, 15 May 2015 15:23:30 -0700 Subject: [PATCH] Print more info on mark sweep invalid ref crash. - Add extra info about the field holder. - Suspend threads when verifying roots. Bug: 20557050 Change-Id: Ia1f2269aaa3b1a81d0594e781e439a5decfb82f9 --- runtime/gc/collector/mark_sweep.cc | 45 +++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc index 53e56da09..5401b5644 100644 --- a/runtime/gc/collector/mark_sweep.cc +++ b/runtime/gc/collector/mark_sweep.cc @@ -373,8 +373,7 @@ class MarkSweepMarkObjectSlowPath { : mark_sweep_(mark_sweep), holder_(holder), offset_(offset) { } - void operator()(const Object* obj) const ALWAYS_INLINE - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + void operator()(const Object* obj) const ALWAYS_INLINE NO_THREAD_SAFETY_ANALYSIS { if (kProfileLargeObjects) { // TODO: Differentiate between marking and testing somehow. ++mark_sweep_->large_object_test_; @@ -385,17 +384,51 @@ class MarkSweepMarkObjectSlowPath { (kIsDebugBuild && large_object_space != nullptr && !large_object_space->Contains(obj)))) { LOG(INTERNAL_FATAL) << "Tried to mark " << obj << " not contained by any spaces"; - LOG(INTERNAL_FATAL) << "Attempting see if it's a bad root"; - mark_sweep_->VerifyRoots(); if (holder_ != nullptr) { + size_t holder_size = holder_->SizeOf(); ArtField* field = holder_->FindFieldByOffset(offset_); - LOG(INTERNAL_FATAL) << "Field info: holder=" << holder_ + LOG(INTERNAL_FATAL) << "Field info: " + << " holder=" << holder_ + << " holder_size=" << holder_size << " holder_type=" << PrettyTypeOf(holder_) << " offset=" << offset_.Uint32Value() - << " field=" << (field != nullptr ? field->GetName() : "nullptr"); + << " field=" << (field != nullptr ? field->GetName() : "nullptr") + << " field_type=" + << (field != nullptr ? field->GetTypeDescriptor() : "") + << " first_ref_field_offset=" + << (holder_->IsClass() + ? holder_->AsClass()->GetFirstReferenceStaticFieldOffset() + : holder_->GetClass()->GetFirstReferenceInstanceFieldOffset()) + << " num_of_ref_fields=" + << (holder_->IsClass() + ? holder_->AsClass()->NumReferenceStaticFields() + : holder_->GetClass()->NumReferenceInstanceFields()) + << "\n"; } PrintFileToLog("/proc/self/maps", LogSeverity::INTERNAL_FATAL); MemMap::DumpMaps(LOG(INTERNAL_FATAL), true); + { + LOG(INTERNAL_FATAL) << "Attempting see if it's a bad root"; + Thread* self = Thread::Current(); + if (Locks::mutator_lock_->IsExclusiveHeld(self)) { + mark_sweep_->VerifyRoots(); + } else { + const bool heap_bitmap_exclusive_locked = + Locks::heap_bitmap_lock_->IsExclusiveHeld(self); + if (heap_bitmap_exclusive_locked) { + Locks::heap_bitmap_lock_->ExclusiveUnlock(self); + } + Locks::mutator_lock_->SharedUnlock(self); + ThreadList* tl = Runtime::Current()->GetThreadList(); + tl->SuspendAll(__FUNCTION__); + mark_sweep_->VerifyRoots(); + tl->ResumeAll(); + Locks::mutator_lock_->SharedLock(self); + if (heap_bitmap_exclusive_locked) { + Locks::heap_bitmap_lock_->ExclusiveLock(self); + } + } + } LOG(FATAL) << "Can't mark invalid object"; } } -- 2.11.0