summaryrefslogtreecommitdiffstats
path: root/runtime/gc
diff options
context:
space:
mode:
authorHiroshi Yamauchi <yamauchi@google.com>2015-05-15 15:23:30 -0700
committerHiroshi Yamauchi <yamauchi@google.com>2015-05-15 15:46:33 -0700
commit1e1a47204984e3b72c4a753a2beb704350f38373 (patch)
tree1c0aca46b9a83b6027fbe42dabf0a8e66f406c2d /runtime/gc
parent577d24cc9e330afb21ab7a5f0d95f84b88745e55 (diff)
downloadart-1e1a47204984e3b72c4a753a2beb704350f38373.zip
art-1e1a47204984e3b72c4a753a2beb704350f38373.tar.gz
art-1e1a47204984e3b72c4a753a2beb704350f38373.tar.bz2
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
Diffstat (limited to 'runtime/gc')
-rw-r--r--runtime/gc/collector/mark_sweep.cc45
1 files changed, 39 insertions, 6 deletions
diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc
index 53e56da..5401b56 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";
}
}