heap_verification_test.cc revision e27c2136d7ad56352ecc09505d3a2733671a0431
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "common_runtime_test.h" 18 19#include "base/memory_tool.h" 20#include "class_linker-inl.h" 21#include "handle_scope-inl.h" 22#include "mirror/object-inl.h" 23#include "mirror/object_array-inl.h" 24#include "mirror/string.h" 25#include "runtime.h" 26#include "scoped_thread_state_change-inl.h" 27#include "verification.h" 28 29namespace art { 30namespace gc { 31 32class VerificationTest : public CommonRuntimeTest { 33 protected: 34 VerificationTest() {} 35 36 template <class T> 37 mirror::ObjectArray<T>* AllocObjectArray(Thread* self, size_t length) 38 REQUIRES_SHARED(Locks::mutator_lock_) { 39 ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); 40 return mirror::ObjectArray<T>::Alloc( 41 self, 42 class_linker->GetClassRoot(ClassLinker::ClassRoot::kObjectArrayClass), 43 length); 44 } 45}; 46 47TEST_F(VerificationTest, IsValidHeapObjectAddress) { 48 ScopedObjectAccess soa(Thread::Current()); 49 const Verification* const v = Runtime::Current()->GetHeap()->GetVerification(); 50 EXPECT_FALSE(v->IsValidHeapObjectAddress(reinterpret_cast<const void*>(1))); 51 EXPECT_FALSE(v->IsValidHeapObjectAddress(reinterpret_cast<const void*>(4))); 52 EXPECT_FALSE(v->IsValidHeapObjectAddress(nullptr)); 53 VariableSizedHandleScope hs(soa.Self()); 54 Handle<mirror::String> string( 55 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "test"))); 56 EXPECT_TRUE(v->IsValidHeapObjectAddress(string.Get())); 57 // Address in the heap that isn't aligned. 58 const void* unaligned_address = 59 reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(string.Get()) + 1); 60 EXPECT_TRUE(v->IsAddressInHeapSpace(unaligned_address)); 61 EXPECT_FALSE(v->IsValidHeapObjectAddress(unaligned_address)); 62 EXPECT_TRUE(v->IsValidHeapObjectAddress(string->GetClass())); 63 const uintptr_t uint_klass = reinterpret_cast<uintptr_t>(string->GetClass()); 64 // Not actually a valid object but the verification can't know that. Guaranteed to be inside a 65 // heap space. 66 EXPECT_TRUE(v->IsValidHeapObjectAddress( 67 reinterpret_cast<const void*>(uint_klass + kObjectAlignment))); 68 EXPECT_FALSE(v->IsValidHeapObjectAddress( 69 reinterpret_cast<const void*>(&uint_klass))); 70} 71 72TEST_F(VerificationTest, IsValidClassOrNotInHeap) { 73 ScopedObjectAccess soa(Thread::Current()); 74 VariableSizedHandleScope hs(soa.Self()); 75 Handle<mirror::String> string( 76 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "test"))); 77 const Verification* const v = Runtime::Current()->GetHeap()->GetVerification(); 78 EXPECT_FALSE(v->IsValidClass(reinterpret_cast<const void*>(1))); 79 EXPECT_FALSE(v->IsValidClass(reinterpret_cast<const void*>(4))); 80 EXPECT_FALSE(v->IsValidClass(nullptr)); 81 EXPECT_TRUE(v->IsValidClass(string->GetClass())); 82 EXPECT_FALSE(v->IsValidClass(string.Get())); 83} 84 85TEST_F(VerificationTest, IsValidClassInHeap) { 86 TEST_DISABLED_FOR_MEMORY_TOOL(); 87 ScopedObjectAccess soa(Thread::Current()); 88 VariableSizedHandleScope hs(soa.Self()); 89 Handle<mirror::String> string( 90 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "test"))); 91 const Verification* const v = Runtime::Current()->GetHeap()->GetVerification(); 92 const uintptr_t uint_klass = reinterpret_cast<uintptr_t>(string->GetClass()); 93 EXPECT_FALSE(v->IsValidClass(reinterpret_cast<const void*>(uint_klass - kObjectAlignment))); 94 EXPECT_FALSE(v->IsValidClass(reinterpret_cast<const void*>(&uint_klass))); 95} 96 97TEST_F(VerificationTest, DumpInvalidObjectInfo) { 98 ScopedLogSeverity sls(LogSeverity::INFO); 99 ScopedObjectAccess soa(Thread::Current()); 100 Runtime* const runtime = Runtime::Current(); 101 VariableSizedHandleScope hs(soa.Self()); 102 const Verification* const v = runtime->GetHeap()->GetVerification(); 103 LOG(INFO) << v->DumpObjectInfo(reinterpret_cast<const void*>(1), "obj"); 104 LOG(INFO) << v->DumpObjectInfo(reinterpret_cast<const void*>(4), "obj"); 105 LOG(INFO) << v->DumpObjectInfo(nullptr, "obj"); 106} 107 108TEST_F(VerificationTest, DumpValidObjectInfo) { 109 TEST_DISABLED_FOR_MEMORY_TOOL(); 110 ScopedLogSeverity sls(LogSeverity::INFO); 111 ScopedObjectAccess soa(Thread::Current()); 112 Runtime* const runtime = Runtime::Current(); 113 VariableSizedHandleScope hs(soa.Self()); 114 Handle<mirror::String> string( 115 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "obj"))); 116 Handle<mirror::ObjectArray<mirror::Object>> arr( 117 hs.NewHandle(AllocObjectArray<mirror::Object>(soa.Self(), 256))); 118 const Verification* const v = runtime->GetHeap()->GetVerification(); 119 LOG(INFO) << v->DumpObjectInfo(string.Get(), "test"); 120 LOG(INFO) << v->DumpObjectInfo(string->GetClass(), "obj"); 121 const uintptr_t uint_klass = reinterpret_cast<uintptr_t>(string->GetClass()); 122 LOG(INFO) << v->DumpObjectInfo(reinterpret_cast<const void*>(uint_klass - kObjectAlignment), 123 "obj"); 124 LOG(INFO) << v->DumpObjectInfo(reinterpret_cast<const void*>(&uint_klass), "obj"); 125 LOG(INFO) << v->DumpObjectInfo(arr.Get(), "arr"); 126} 127 128TEST_F(VerificationTest, LogHeapCorruption) { 129 TEST_DISABLED_FOR_MEMORY_TOOL(); 130 ScopedLogSeverity sls(LogSeverity::INFO); 131 ScopedObjectAccess soa(Thread::Current()); 132 Runtime* const runtime = Runtime::Current(); 133 VariableSizedHandleScope hs(soa.Self()); 134 Handle<mirror::String> string( 135 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "obj"))); 136 using ObjArray = mirror::ObjectArray<mirror::Object>; 137 Handle<ObjArray> arr( 138 hs.NewHandle(AllocObjectArray<mirror::Object>(soa.Self(), 256))); 139 const Verification* const v = runtime->GetHeap()->GetVerification(); 140 arr->Set(0, string.Get()); 141 // Test normal cases. 142 v->LogHeapCorruption(arr.Get(), ObjArray::DataOffset(kHeapReferenceSize), string.Get(), false); 143 v->LogHeapCorruption(string.Get(), mirror::Object::ClassOffset(), string->GetClass(), false); 144 // Test null holder cases. 145 v->LogHeapCorruption(nullptr, MemberOffset(0), string.Get(), false); 146 v->LogHeapCorruption(nullptr, MemberOffset(0), arr.Get(), false); 147} 148 149} // namespace gc 150} // namespace art 151