• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
18 #include "alloc/HeapBitmap.h"
19 #include "alloc/HeapSource.h"
20 #include "alloc/Verify.h"
21 #include "alloc/Visit.h"
22 
23 /*
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  */
dumpReferencesVisitor(void * pObj,void * arg)28 static 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 
37 /*
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  */
dumpReferencesCallback(Object * obj,void * arg)41 static void dumpReferencesCallback(Object *obj, void *arg)
42 {
43     if (obj == (Object *)arg) {
44         return;
45     }
46     dvmVisitObject(dumpReferencesVisitor, obj, &arg);
47     if (arg == NULL) {
48         ALOGD("Found %p in the heap @ %p", arg, obj);
49         dvmDumpObject(obj);
50     }
51 }
52 
53 /*
54  * Visitor applied to each root to search for things that point to an
55  * object.  Logs a message when a match is found.
56  */
dumpReferencesRootVisitor(void * ptr,u4 threadId,RootType type,void * arg)57 static void dumpReferencesRootVisitor(void *ptr, u4 threadId,
58                                       RootType type, void *arg)
59 {
60     Object *obj = *(Object **)ptr;
61     Object *lookingFor = *(Object **)arg;
62     if (obj == lookingFor) {
63         ALOGD("Found %p in a root @ %p", arg, ptr);
64     }
65 }
66 
67 /*
68  * Searches the roots and heap for object references.
69  */
dumpReferences(const Object * obj)70 static void dumpReferences(const Object *obj)
71 {
72     HeapBitmap *bitmap = dvmHeapSourceGetLiveBits();
73     void *arg = (void *)obj;
74     dvmVisitRoots(dumpReferencesRootVisitor, arg);
75     dvmHeapBitmapWalk(bitmap, dumpReferencesCallback, arg);
76 }
77 
78 /*
79  * Checks that the given reference points to a valid object.
80  */
verifyReference(void * addr,void * arg)81 static void verifyReference(void *addr, void *arg)
82 {
83     Object *obj;
84     bool isValid;
85 
86     assert(addr != NULL);
87     obj = *(Object **)addr;
88     if (obj == NULL) {
89         isValid = true;
90     } else {
91         isValid = dvmIsValidObject(obj);
92     }
93     if (!isValid) {
94         Object **parent = (Object **)arg;
95         if (*parent != NULL) {
96             ALOGE("Verify of object %p failed", *parent);
97             dvmDumpObject(*parent);
98             *parent = NULL;
99         }
100         ALOGE("Verify of reference %p @ %p failed", obj, addr);
101         dvmDumpObject(obj);
102     }
103 }
104 
105 /*
106  * Verifies an object reference.
107  */
dvmVerifyObject(const Object * obj)108 void dvmVerifyObject(const Object *obj)
109 {
110     Object *arg = const_cast<Object*>(obj);
111     dvmVisitObject(verifyReference, arg, &arg);
112     if (arg == NULL) {
113         dumpReferences(obj);
114         dvmAbort();
115     }
116 }
117 
118 /*
119  * Helper function to call dvmVerifyObject from a bitmap walker.
120  */
verifyBitmapCallback(Object * obj,void * arg)121 static void verifyBitmapCallback(Object *obj, void *arg)
122 {
123     dvmVerifyObject(obj);
124 }
125 
126 /*
127  * Verifies the object references in a heap bitmap. Assumes the VM is
128  * suspended.
129  */
dvmVerifyBitmap(const HeapBitmap * bitmap)130 void dvmVerifyBitmap(const HeapBitmap *bitmap)
131 {
132     dvmHeapBitmapWalk(bitmap, verifyBitmapCallback, NULL);
133 }
134 
135 /*
136  * Helper function to call verifyReference from the root verifier.
137  */
verifyRootReference(void * addr,u4 threadId,RootType type,void * arg)138 static void verifyRootReference(void *addr, u4 threadId,
139                                 RootType type, void *arg)
140 {
141     verifyReference(addr, arg);
142 }
143 
144 /*
145  * Verifies references in the roots.
146  */
dvmVerifyRoots()147 void dvmVerifyRoots()
148 {
149     dvmVisitRoots(verifyRootReference, NULL);
150 }
151