• 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 
dumpReferencesVisitor(void * pObj,void * arg)23 static 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 
dumpReferencesCallback(void * ptr,void * arg)32 static void dumpReferencesCallback(void *ptr, void *arg)
33 {
34     Object *obj = arg;
35     if (ptr == obj) {
36         LOGD("skipping %p == %p", ptr, obj);
37         return;
38     }
39     dvmVisitObject(dumpReferencesVisitor, ptr, &obj);
40     if (obj == NULL) {
41         LOGD("Found %p in the heap @ %p", arg, ptr);
42         dvmDumpObject(ptr);
43     }
44 }
45 
dumpReferencesRootVisitor(void * ptr,void * arg)46 static void dumpReferencesRootVisitor(void *ptr, void *arg)
47 {
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  */
dumpReferences(const Object * obj)58 static 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 
66 /*
67  * Checks that the given reference points to a valid object.
68  */
verifyReference(void * addr,void * arg)69 static void verifyReference(void *addr, void *arg)
70 {
71     Object *obj;
72     bool isValid;
73 
74     assert(addr != NULL);
75     obj = *(Object **)addr;
76     if (obj == NULL) {
77         isValid = true;
78     } else {
79         isValid = dvmIsValidObject(obj);
80     }
81     if (!isValid) {
82         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);
90     }
91 }
92 
93 /*
94  * Verifies an object reference.
95  */
dvmVerifyObject(const Object * obj)96 void dvmVerifyObject(const Object *obj)
97 {
98     Object *arg = (Object *)obj;
99     dvmVisitObject(verifyReference, (Object *)obj, &arg);
100     if (arg == NULL) {
101         dumpReferences(obj);
102         dvmAbort();
103     }
104 }
105 
106 /*
107  * Helper function to call dvmVerifyObject from a bitmap walker.
108  */
verifyBitmapCallback(void * ptr,void * arg)109 static void verifyBitmapCallback(void *ptr, void *arg)
110 {
111     dvmVerifyObject(ptr);
112 }
113 
114 /*
115  * Verifies the object references in a heap bitmap. Assumes the VM is
116  * suspended.
117  */
dvmVerifyBitmap(const HeapBitmap * bitmap)118 void dvmVerifyBitmap(const HeapBitmap *bitmap)
119 {
120     dvmHeapBitmapWalk(bitmap, verifyBitmapCallback, NULL);
121 }
122 
123 /*
124  * Verifies references in the roots.
125  */
dvmVerifyRoots(void)126 void dvmVerifyRoots(void)
127 {
128     dvmVisitRoots(verifyReference, NULL);
129 }
130