11e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro/* 21e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * Copyright (C) 2010 The Android Open Source Project 31e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * 41e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * Licensed under the Apache License, Version 2.0 (the "License"); 51e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * you may not use this file except in compliance with the License. 61e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * You may obtain a copy of the License at 71e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * 81e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * http://www.apache.org/licenses/LICENSE-2.0 91e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * 101e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * Unless required by applicable law or agreed to in writing, software 111e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * distributed under the License is distributed on an "AS IS" BASIS, 121e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * See the License for the specific language governing permissions and 141e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * limitations under the License. 151e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro */ 161e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro 171e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro#include "Dalvik.h" 18adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro#include "alloc/HeapBitmap.h" 19c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro#include "alloc/HeapSource.h" 201e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro#include "alloc/Verify.h" 21adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro#include "alloc/Visit.h" 221e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro 2397c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro/* 2497c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro * Visitor applied to each reference field when searching for things 2597c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro * that point to an object. Sets the argument to NULL when a match is 2697c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro * found. 2797c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro */ 28c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapirostatic void dumpReferencesVisitor(void *pObj, void *arg) 29c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro{ 30c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro Object *obj = *(Object **)pObj; 31c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro Object *lookingFor = *(Object **)arg; 32c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro if (lookingFor != NULL && lookingFor == obj) { 33c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro *(Object **)arg = NULL; 34c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro } 35c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro} 36c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro 3797c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro/* 3897c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro * Visitor applied to each bitmap element to search for things that 3997c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro * point to an object. Logs a message when a match is found. 4097c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro */ 410d92a4072c00434e95a03642a4944acf81a81cc3Carl Shapirostatic void dumpReferencesCallback(Object *obj, void *arg) 42c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro{ 430d92a4072c00434e95a03642a4944acf81a81cc3Carl Shapiro if (obj == (Object *)arg) { 44c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro return; 45c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro } 460d92a4072c00434e95a03642a4944acf81a81cc3Carl Shapiro dvmVisitObject(dumpReferencesVisitor, obj, &arg); 470d92a4072c00434e95a03642a4944acf81a81cc3Carl Shapiro if (arg == NULL) { 48062bf509a77fce9dfcb7e7b2e401cf2a124d83d5Steve Block ALOGD("Found %p in the heap @ %p", arg, obj); 490d92a4072c00434e95a03642a4944acf81a81cc3Carl Shapiro dvmDumpObject(obj); 50c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro } 51c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro} 52c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro 5397c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro/* 5497c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro * Visitor applied to each root to search for things that point to an 5597c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro * object. Logs a message when a match is found. 5697c3dddbcf9b7426ef2f10e0903eeb4b5a884733Carl Shapiro */ 5707018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapirostatic void dumpReferencesRootVisitor(void *ptr, u4 threadId, 5807018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapiro RootType type, void *arg) 59c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro{ 60c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro Object *obj = *(Object **)ptr; 61c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro Object *lookingFor = *(Object **)arg; 62c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro if (obj == lookingFor) { 63062bf509a77fce9dfcb7e7b2e401cf2a124d83d5Steve Block ALOGD("Found %p in a root @ %p", arg, ptr); 64c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro } 65c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro} 66c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro 67c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro/* 68c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro * Searches the roots and heap for object references. 69c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro */ 70c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapirostatic void dumpReferences(const Object *obj) 71c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro{ 72c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro HeapBitmap *bitmap = dvmHeapSourceGetLiveBits(); 73c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro void *arg = (void *)obj; 74c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro dvmVisitRoots(dumpReferencesRootVisitor, arg); 75c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro dvmHeapBitmapWalk(bitmap, dumpReferencesCallback, arg); 76c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro} 77c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro 78c85ec00dd616da05191f08934f93b711aa6f20ddCarl Shapiro/* 791fbfcab90fb4f03fa9053ce2cd567f84904fefefCarl Shapiro * Checks that the given reference points to a valid object. 80c85ec00dd616da05191f08934f93b711aa6f20ddCarl Shapiro */ 811fbfcab90fb4f03fa9053ce2cd567f84904fefefCarl Shapirostatic void verifyReference(void *addr, void *arg) 82f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro{ 83c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro Object *obj; 84f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro bool isValid; 85f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro 861fbfcab90fb4f03fa9053ce2cd567f84904fefefCarl Shapiro assert(addr != NULL); 87c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro obj = *(Object **)addr; 88f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro if (obj == NULL) { 89f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro isValid = true; 90f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro } else { 91f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro isValid = dvmIsValidObject(obj); 92f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro } 93f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro if (!isValid) { 94fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro Object **parent = (Object **)arg; 95c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro if (*parent != NULL) { 96c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Verify of object %p failed", *parent); 97c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro dvmDumpObject(*parent); 98c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro *parent = NULL; 99c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro } 100c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Verify of reference %p @ %p failed", obj, addr); 101c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro dvmDumpObject(obj); 102f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro } 103f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro} 1041e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro 1051e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro/* 1061fbfcab90fb4f03fa9053ce2cd567f84904fefefCarl Shapiro * Verifies an object reference. 1071e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro */ 1081e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapirovoid dvmVerifyObject(const Object *obj) 1091e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro{ 1100d92a4072c00434e95a03642a4944acf81a81cc3Carl Shapiro Object *arg = const_cast<Object*>(obj); 1110d92a4072c00434e95a03642a4944acf81a81cc3Carl Shapiro dvmVisitObject(verifyReference, arg, &arg); 112c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro if (arg == NULL) { 113c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro dumpReferences(obj); 114c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro dvmAbort(); 115c44bca6530787454ee794cf2f83c1c6671a93aa8Carl Shapiro } 1161e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro} 1171e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro 1181e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro/* 1191e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro * Helper function to call dvmVerifyObject from a bitmap walker. 1201e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro */ 1210d92a4072c00434e95a03642a4944acf81a81cc3Carl Shapirostatic void verifyBitmapCallback(Object *obj, void *arg) 1221e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro{ 1230d92a4072c00434e95a03642a4944acf81a81cc3Carl Shapiro dvmVerifyObject(obj); 1241e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro} 1251e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro 1261e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro/* 127962adba4e5db286a36bc8024f5c023bcf6f29312Barry Hayes * Verifies the object references in a heap bitmap. Assumes the VM is 128962adba4e5db286a36bc8024f5c023bcf6f29312Barry Hayes * suspended. 1291e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro */ 130962adba4e5db286a36bc8024f5c023bcf6f29312Barry Hayesvoid dvmVerifyBitmap(const HeapBitmap *bitmap) 1311e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro{ 1321e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro dvmHeapBitmapWalk(bitmap, verifyBitmapCallback, NULL); 1331e714bbd8230ac6fb9e3a8e9e25bca687132c82aCarl Shapiro} 134f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro 135f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro/* 13607018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapiro * Helper function to call verifyReference from the root verifier. 13707018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapiro */ 13807018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapirostatic void verifyRootReference(void *addr, u4 threadId, 13907018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapiro RootType type, void *arg) 14007018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapiro{ 14107018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapiro verifyReference(addr, arg); 14207018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapiro} 14307018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapiro 14407018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapiro/* 1451fbfcab90fb4f03fa9053ce2cd567f84904fefefCarl Shapiro * Verifies references in the roots. 146f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro */ 1471e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmVerifyRoots() 148f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro{ 14907018e2d14b012ae433a0d82025a885ed8debc3bCarl Shapiro dvmVisitRoots(verifyRootReference, NULL); 150f571825e42a0daa957b99f8cf7598f517b504fa3Carl Shapiro} 151