blob: f36f44bf110ba722dc047e550ca641b4dc9e044b [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 Shapiro97c3ddd2011-02-28 18:14:22 -080023/*
24 * Visitor applied to each reference field when searching for things
25 * that point to an object. Sets the argument to NULL when a match is
26 * found.
27 */
Carl Shapiroc44bca62010-08-27 15:21:13 -070028static void dumpReferencesVisitor(void *pObj, void *arg)
29{
30 Object *obj = *(Object **)pObj;
31 Object *lookingFor = *(Object **)arg;
32 if (lookingFor != NULL && lookingFor == obj) {
33 *(Object **)arg = NULL;
34 }
35}
36
Carl Shapiro97c3ddd2011-02-28 18:14:22 -080037/*
38 * Visitor applied to each bitmap element to search for things that
39 * point to an object. Logs a message when a match is found.
40 */
Carl Shapiroc44bca62010-08-27 15:21:13 -070041static void dumpReferencesCallback(void *ptr, void *arg)
42{
Carl Shapirofc75f3e2010-12-07 11:43:38 -080043 Object *obj = (Object *)arg;
Carl Shapiroc44bca62010-08-27 15:21:13 -070044 if (ptr == obj) {
Carl Shapiroc44bca62010-08-27 15:21:13 -070045 return;
46 }
Carl Shapirofc75f3e2010-12-07 11:43:38 -080047 dvmVisitObject(dumpReferencesVisitor, (Object *)ptr, &obj);
Carl Shapiroc44bca62010-08-27 15:21:13 -070048 if (obj == NULL) {
49 LOGD("Found %p in the heap @ %p", arg, ptr);
Carl Shapirofc75f3e2010-12-07 11:43:38 -080050 dvmDumpObject((Object *)ptr);
Carl Shapiroc44bca62010-08-27 15:21:13 -070051 }
52}
53
Carl Shapiro97c3ddd2011-02-28 18:14:22 -080054/*
55 * Visitor applied to each root to search for things that point to an
56 * object. Logs a message when a match is found.
57 */
Carl Shapiro07018e22010-10-26 21:07:41 -070058static void dumpReferencesRootVisitor(void *ptr, u4 threadId,
59 RootType type, void *arg)
Carl Shapiroc44bca62010-08-27 15:21:13 -070060{
61 Object *obj = *(Object **)ptr;
62 Object *lookingFor = *(Object **)arg;
63 if (obj == lookingFor) {
64 LOGD("Found %p in a root @ %p", arg, ptr);
65 }
66}
67
68/*
69 * Searches the roots and heap for object references.
70 */
71static void dumpReferences(const Object *obj)
72{
73 HeapBitmap *bitmap = dvmHeapSourceGetLiveBits();
74 void *arg = (void *)obj;
75 dvmVisitRoots(dumpReferencesRootVisitor, arg);
76 dvmHeapBitmapWalk(bitmap, dumpReferencesCallback, arg);
77}
78
Carl Shapiroc85ec002010-04-05 19:36:37 -070079/*
Carl Shapiro1fbfcab2010-07-22 17:29:23 -070080 * Checks that the given reference points to a valid object.
Carl Shapiroc85ec002010-04-05 19:36:37 -070081 */
Carl Shapiro1fbfcab2010-07-22 17:29:23 -070082static void verifyReference(void *addr, void *arg)
Carl Shapirof5718252010-05-11 20:55:13 -070083{
Carl Shapiroc44bca62010-08-27 15:21:13 -070084 Object *obj;
Carl Shapirof5718252010-05-11 20:55:13 -070085 bool isValid;
86
Carl Shapiro1fbfcab2010-07-22 17:29:23 -070087 assert(addr != NULL);
Carl Shapiroc44bca62010-08-27 15:21:13 -070088 obj = *(Object **)addr;
Carl Shapirof5718252010-05-11 20:55:13 -070089 if (obj == NULL) {
90 isValid = true;
91 } else {
92 isValid = dvmIsValidObject(obj);
93 }
94 if (!isValid) {
Carl Shapirofc75f3e2010-12-07 11:43:38 -080095 Object **parent = (Object **)arg;
Carl Shapiroc44bca62010-08-27 15:21:13 -070096 if (*parent != NULL) {
97 LOGE("Verify of object %p failed", *parent);
98 dvmDumpObject(*parent);
99 *parent = NULL;
100 }
101 LOGE("Verify of reference %p @ %p failed", obj, addr);
102 dvmDumpObject(obj);
Carl Shapirof5718252010-05-11 20:55:13 -0700103 }
104}
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700105
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700106/*
Carl Shapiro1fbfcab2010-07-22 17:29:23 -0700107 * Verifies an object reference.
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700108 */
109void dvmVerifyObject(const Object *obj)
110{
Carl Shapiroc44bca62010-08-27 15:21:13 -0700111 Object *arg = (Object *)obj;
112 dvmVisitObject(verifyReference, (Object *)obj, &arg);
113 if (arg == NULL) {
114 dumpReferences(obj);
115 dvmAbort();
116 }
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700117}
118
119/*
120 * Helper function to call dvmVerifyObject from a bitmap walker.
121 */
Carl Shapiroc44bca62010-08-27 15:21:13 -0700122static void verifyBitmapCallback(void *ptr, void *arg)
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700123{
Carl Shapirofc75f3e2010-12-07 11:43:38 -0800124 dvmVerifyObject((Object *)ptr);
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700125}
126
127/*
Barry Hayes962adba2010-03-17 12:12:39 -0700128 * Verifies the object references in a heap bitmap. Assumes the VM is
129 * suspended.
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700130 */
131void dvmVerifyBitmap(const HeapBitmap *bitmap)
132{
Barry Hayes962adba2010-03-17 12:12:39 -0700133 dvmHeapBitmapWalk(bitmap, verifyBitmapCallback, NULL);
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700134}
Carl Shapirof5718252010-05-11 20:55:13 -0700135
136/*
Carl Shapiro07018e22010-10-26 21:07:41 -0700137 * Helper function to call verifyReference from the root verifier.
138 */
139static void verifyRootReference(void *addr, u4 threadId,
140 RootType type, void *arg)
141{
142 verifyReference(addr, arg);
143}
144
145/*
Carl Shapiro1fbfcab2010-07-22 17:29:23 -0700146 * Verifies references in the roots.
Carl Shapirof5718252010-05-11 20:55:13 -0700147 */
148void dvmVerifyRoots(void)
149{
Carl Shapiro07018e22010-10-26 21:07:41 -0700150 dvmVisitRoots(verifyRootReference, NULL);
Carl Shapirof5718252010-05-11 20:55:13 -0700151}