diff options
-rw-r--r-- | libartbase/base/memory_tool.h | 2 | ||||
-rw-r--r-- | runtime/gc/collector/mark_compact-inl.h | 21 |
2 files changed, 16 insertions, 7 deletions
diff --git a/libartbase/base/memory_tool.h b/libartbase/base/memory_tool.h index 675ceb2cfd..4a93a9642f 100644 --- a/libartbase/base/memory_tool.h +++ b/libartbase/base/memory_tool.h @@ -68,10 +68,12 @@ constexpr size_t kMemoryToolStackGuardSizeScale = 1; #if __has_feature(hwaddress_sanitizer) # define HWADDRESS_SANITIZER +constexpr bool kHwAsanEnabled = true; // NB: The attribute also implies NO_INLINE. If inlined, the hwasan attribute would be lost. // If method is also separately marked as ALWAYS_INLINE, the NO_INLINE takes precedence. # define ATTRIBUTE_NO_SANITIZE_HWADDRESS __attribute__((no_sanitize("hwaddress"), noinline)) #else +constexpr bool kHwAsanEnabled = false; # define ATTRIBUTE_NO_SANITIZE_HWADDRESS #endif diff --git a/runtime/gc/collector/mark_compact-inl.h b/runtime/gc/collector/mark_compact-inl.h index 18095e8b58..24d47638b1 100644 --- a/runtime/gc/collector/mark_compact-inl.h +++ b/runtime/gc/collector/mark_compact-inl.h @@ -266,9 +266,10 @@ inline bool MarkCompact::VerifyRootSingleUpdate(void* root, mirror::Object* old_ref, const RootInfo& info) { // ASAN promotes stack-frames to heap in order to detect - // stack-use-after-return issues. So skip using this double-root update - // detection on ASAN as well. - if (kIsDebugBuild && !kMemoryToolIsAvailable) { + // stack-use-after-return issues. And HWASAN has pointers tagged, which makes + // it difficult to recognize and prevent stack pointers from being checked. + // So skip using double-root update detection on ASANs. + if (kIsDebugBuild && !kMemoryToolIsAvailable && !kHwAsanEnabled) { void* stack_low_addr = stack_low_addr_; void* stack_high_addr = stack_high_addr_; if (!HasAddress(old_ref)) { @@ -279,15 +280,21 @@ inline bool MarkCompact::VerifyRootSingleUpdate(void* root, stack_low_addr = self->GetStackEnd(); stack_high_addr = reinterpret_cast<char*>(stack_low_addr) + self->GetStackSize(); } - if (root < stack_low_addr || root > stack_high_addr) { + if (std::less<void*>{}(root, stack_low_addr) || std::greater<void*>{}(root, stack_high_addr)) { bool inserted; { MutexLock mu(self, lock_); inserted = updated_roots_->insert(root).second; } - DCHECK(inserted) << "root=" << root << " old_ref=" << old_ref - << " stack_low_addr=" << stack_low_addr - << " stack_high_addr=" << stack_high_addr; + if (!inserted) { + std::ostringstream oss; + heap_->DumpSpaces(oss); + MemMap::DumpMaps(oss, /* terse= */ true); + CHECK(inserted) << "root=" << root << " old_ref=" << old_ref + << " stack_low_addr=" << stack_low_addr + << " stack_high_addr=" << stack_high_addr << " maps\n" + << oss.str(); + } } DCHECK(reinterpret_cast<uint8_t*>(old_ref) >= black_allocations_begin_ || live_words_bitmap_->Test(old_ref)) |