blob: 5ce692cb1f9789c32d0008e5bbaeff854eac0148 [file] [log] [blame]
Carl Shapiro1e714bb2010-03-16 03:26:49 -07001/*
2 * Copyright (C) 2010 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 "Dalvik.h"
Carl Shapiroadc346f2010-06-03 23:01:39 -070018#include "alloc/HeapBitmap.h"
Carl Shapiroc44bca62010-08-27 15:21:13 -070019#include "alloc/HeapSource.h"
Carl Shapiro1e714bb2010-03-16 03:26:49 -070020#include "alloc/Verify.h"
Carl Shapiroadc346f2010-06-03 23:01:39 -070021#include "alloc/Visit.h"
Carl Shapiro1e714bb2010-03-16 03:26:49 -070022
Carl Shapiroc44bca62010-08-27 15:21:13 -070023static void dumpReferencesVisitor(void *pObj, void *arg)
24{
25 Object *obj = *(Object **)pObj;
26 Object *lookingFor = *(Object **)arg;
27 if (lookingFor != NULL && lookingFor == obj) {
28 *(Object **)arg = NULL;
29 }
30}
31
32static void dumpReferencesCallback(void *ptr, void *arg)
33{
34 Object *obj = arg;
35 if (ptr == obj) {
Carl Shapiroc44bca62010-08-27 15:21:13 -070036 return;
37 }
38 dvmVisitObject(dumpReferencesVisitor, ptr, &obj);
39 if (obj == NULL) {
40 LOGD("Found %p in the heap @ %p", arg, ptr);
41 dvmDumpObject(ptr);
42 }
43}
44
Carl Shapiro07018e22010-10-26 21:07:41 -070045static void dumpReferencesRootVisitor(void *ptr, u4 threadId,
46 RootType type, void *arg)
Carl Shapiroc44bca62010-08-27 15:21:13 -070047{
48 Object *obj = *(Object **)ptr;
49 Object *lookingFor = *(Object **)arg;
50 if (obj == lookingFor) {
51 LOGD("Found %p in a root @ %p", arg, ptr);
52 }
53}
54
55/*
56 * Searches the roots and heap for object references.
57 */
58static void dumpReferences(const Object *obj)
59{
60 HeapBitmap *bitmap = dvmHeapSourceGetLiveBits();
61 void *arg = (void *)obj;
62 dvmVisitRoots(dumpReferencesRootVisitor, arg);
63 dvmHeapBitmapWalk(bitmap, dumpReferencesCallback, arg);
64}
65
Carl Shapiroc85ec002010-04-05 19:36:37 -070066/*
Carl Shapiro1fbfcab2010-07-22 17:29:23 -070067 * Checks that the given reference points to a valid object.
Carl Shapiroc85ec002010-04-05 19:36:37 -070068 */
Carl Shapiro1fbfcab2010-07-22 17:29:23 -070069static void verifyReference(void *addr, void *arg)
Carl Shapirof5718252010-05-11 20:55:13 -070070{
Carl Shapiroc44bca62010-08-27 15:21:13 -070071 Object *obj;
Carl Shapirof5718252010-05-11 20:55:13 -070072 bool isValid;
73
Carl Shapiro1fbfcab2010-07-22 17:29:23 -070074 assert(addr != NULL);
Carl Shapiroc44bca62010-08-27 15:21:13 -070075 obj = *(Object **)addr;
Carl Shapirof5718252010-05-11 20:55:13 -070076 if (obj == NULL) {
77 isValid = true;
78 } else {
79 isValid = dvmIsValidObject(obj);
80 }
81 if (!isValid) {
Carl Shapiroc44bca62010-08-27 15:21:13 -070082 Object **parent = arg;
83 if (*parent != NULL) {
84 LOGE("Verify of object %p failed", *parent);
85 dvmDumpObject(*parent);
86 *parent = NULL;
87 }
88 LOGE("Verify of reference %p @ %p failed", obj, addr);
89 dvmDumpObject(obj);
Carl Shapirof5718252010-05-11 20:55:13 -070090 }
91}
Carl Shapiro1e714bb2010-03-16 03:26:49 -070092
Carl Shapiro1e714bb2010-03-16 03:26:49 -070093/*
Carl Shapiro1fbfcab2010-07-22 17:29:23 -070094 * Verifies an object reference.
Carl Shapiro1e714bb2010-03-16 03:26:49 -070095 */
96void dvmVerifyObject(const Object *obj)
97{
Carl Shapiroc44bca62010-08-27 15:21:13 -070098 Object *arg = (Object *)obj;
99 dvmVisitObject(verifyReference, (Object *)obj, &arg);
100 if (arg == NULL) {
101 dumpReferences(obj);
102 dvmAbort();
103 }
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700104}
105
106/*
107 * Helper function to call dvmVerifyObject from a bitmap walker.
108 */
Carl Shapiroc44bca62010-08-27 15:21:13 -0700109static void verifyBitmapCallback(void *ptr, void *arg)
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700110{
Carl Shapiroc44bca62010-08-27 15:21:13 -0700111 dvmVerifyObject(ptr);
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700112}
113
114/*
Barry Hayes962adba2010-03-17 12:12:39 -0700115 * Verifies the object references in a heap bitmap. Assumes the VM is
116 * suspended.
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700117 */
118void dvmVerifyBitmap(const HeapBitmap *bitmap)
119{
Barry Hayes962adba2010-03-17 12:12:39 -0700120 dvmHeapBitmapWalk(bitmap, verifyBitmapCallback, NULL);
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700121}
Carl Shapirof5718252010-05-11 20:55:13 -0700122
123/*
Carl Shapiro07018e22010-10-26 21:07:41 -0700124 * Helper function to call verifyReference from the root verifier.
125 */
126static void verifyRootReference(void *addr, u4 threadId,
127 RootType type, void *arg)
128{
129 verifyReference(addr, arg);
130}
131
132/*
Carl Shapiro1fbfcab2010-07-22 17:29:23 -0700133 * Verifies references in the roots.
Carl Shapirof5718252010-05-11 20:55:13 -0700134 */
135void dvmVerifyRoots(void)
136{
Carl Shapiro07018e22010-10-26 21:07:41 -0700137 dvmVisitRoots(verifyRootReference, NULL);
Carl Shapirof5718252010-05-11 20:55:13 -0700138}