diff options
Diffstat (limited to 'vm/alloc/Verify.c')
-rw-r--r-- | vm/alloc/Verify.c | 75 |
1 files changed, 62 insertions, 13 deletions
diff --git a/vm/alloc/Verify.c b/vm/alloc/Verify.c index c4222adce..48168ddc5 100644 --- a/vm/alloc/Verify.c +++ b/vm/alloc/Verify.c @@ -16,49 +16,99 @@ #include "Dalvik.h" #include "alloc/HeapBitmap.h" +#include "alloc/HeapSource.h" #include "alloc/Verify.h" #include "alloc/Visit.h" +static void dumpReferencesVisitor(void *pObj, void *arg) +{ + Object *obj = *(Object **)pObj; + Object *lookingFor = *(Object **)arg; + if (lookingFor != NULL && lookingFor == obj) { + *(Object **)arg = NULL; + } +} + +static void dumpReferencesCallback(void *ptr, void *arg) +{ + Object *obj = arg; + if (ptr == obj) { + LOGD("skipping %p == %p", ptr, obj); + return; + } + dvmVisitObject(dumpReferencesVisitor, ptr, &obj); + if (obj == NULL) { + LOGD("Found %p in the heap @ %p", arg, ptr); + dvmDumpObject(ptr); + } +} + +static void dumpReferencesRootVisitor(void *ptr, void *arg) +{ + Object *obj = *(Object **)ptr; + Object *lookingFor = *(Object **)arg; + if (obj == lookingFor) { + LOGD("Found %p in a root @ %p", arg, ptr); + } +} + +/* + * Searches the roots and heap for object references. + */ +static void dumpReferences(const Object *obj) +{ + HeapBitmap *bitmap = dvmHeapSourceGetLiveBits(); + void *arg = (void *)obj; + dvmVisitRoots(dumpReferencesRootVisitor, arg); + dvmHeapBitmapWalk(bitmap, dumpReferencesCallback, arg); +} + /* * Checks that the given reference points to a valid object. */ static void verifyReference(void *addr, void *arg) { - const Object *obj; + Object *obj; bool isValid; assert(addr != NULL); - obj = *(const Object **)addr; + obj = *(Object **)addr; if (obj == NULL) { isValid = true; } else { isValid = dvmIsValidObject(obj); } if (!isValid) { - LOGE("Verify of object %p @ %p failed", obj, addr); - dvmAbort(); + Object **parent = arg; + if (*parent != NULL) { + LOGE("Verify of object %p failed", *parent); + dvmDumpObject(*parent); + *parent = NULL; + } + LOGE("Verify of reference %p @ %p failed", obj, addr); + dvmDumpObject(obj); } } -static void visitorCallback(void *addr, void *arg) -{ - verifyReference(addr, arg); -} - /* * Verifies an object reference. */ void dvmVerifyObject(const Object *obj) { - dvmVisitObject(visitorCallback, (Object *)obj, NULL); + Object *arg = (Object *)obj; + dvmVisitObject(verifyReference, (Object *)obj, &arg); + if (arg == NULL) { + dumpReferences(obj); + dvmAbort(); + } } /* * Helper function to call dvmVerifyObject from a bitmap walker. */ -static void verifyBitmapCallback(void *ptrs, void *arg) +static void verifyBitmapCallback(void *ptr, void *arg) { - dvmVerifyObject(ptrs); + dvmVerifyObject(ptr); } /* @@ -67,7 +117,6 @@ static void verifyBitmapCallback(void *ptrs, void *arg) */ void dvmVerifyBitmap(const HeapBitmap *bitmap) { - /* TODO: check that locks are held and the VM is suspended. */ dvmHeapBitmapWalk(bitmap, verifyBitmapCallback, NULL); } |