diff options
author | Carl Shapiro <cshapiro@google.com> | 2010-08-27 15:21:13 -0700 |
---|---|---|
committer | Carl Shapiro <cshapiro@google.com> | 2010-09-01 18:37:38 -0700 |
commit | c44bca6530787454ee794cf2f83c1c6671a93aa8 (patch) | |
tree | 9597da792977d565df98e5e9bdccb038927f657c | |
parent | 57ee270b755271166b2349321e5b8b5457731dd7 (diff) | |
download | android_dalvik-c44bca6530787454ee794cf2f83c1c6671a93aa8.tar.gz android_dalvik-c44bca6530787454ee794cf2f83c1c6671a93aa8.tar.bz2 android_dalvik-c44bca6530787454ee794cf2f83c1c6671a93aa8.zip |
Improve the heap verifier's failure report.
Previously, when a reference verify failed we would print the location
of the bad reference and abort. With this change, when a reference
fails to verify we try to print out more context. First, we dump the
object which contains the bad references and print each reference that
failed verification. Following that, we scan the roots and the heap
and print all of the objects which reference the bad object.
-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); } |