Keep track of debugger call results

The debugger can execute arbitrary methods in threads that are stopped
at a breakpoint.  The result is passed back from the target thread to
the debugger through the JDWP thread.  During this time, nothing else
has a copy of the return value, so if it's an object reference we need
to make sure the GC doesn't move or discard it.

The object is added to the "GC don't touch" list by the JDWP code,
but it was happening after the object was passed between threads.
We now register the object right after we get it.

Also, don't call dvmAddTrackedAlloc on a null object.

Bug 3009076

Change-Id: I5ab07a70ad7141b6867707c75843cfb60c35446d
diff --git a/vm/Debugger.c b/vm/Debugger.c
index 1391466..39eb74a 100644
--- a/vm/Debugger.c
+++ b/vm/Debugger.c
@@ -2888,8 +2888,10 @@
      * to preserve that across the method invocation.
      */
     oldExcept = dvmGetException(self);
-    dvmAddTrackedAlloc(oldExcept, self);
-    dvmClearException(self);
+    if (oldExcept != NULL) {
+        dvmAddTrackedAlloc(oldExcept, self);
+        dvmClearException(self);
+    }
 
     oldStatus = dvmChangeStatus(self, THREAD_RUNNING);
 
@@ -2938,11 +2940,23 @@
                 pReq->resultTag, newTag);
             pReq->resultTag = newTag;
         }
+
+        /*
+         * Register the object.  We don't actually need an ObjectId yet,
+         * but we do need to be sure that the GC won't move or discard the
+         * object when we switch out of RUNNING.  The ObjectId conversion
+         * will add the object to the "do not touch" list.
+         *
+         * We can't use the "tracked allocation" mechanism here because
+         * the object is going to be handed off to a different thread.
+         */
+        (void) objectToObjectId(pReq->resultValue.l);
     }
 
-    if (oldExcept != NULL)
+    if (oldExcept != NULL) {
         dvmSetException(self, oldExcept);
-    dvmReleaseTrackedAlloc(oldExcept, self);
+        dvmReleaseTrackedAlloc(oldExcept, self);
+    }
     dvmChangeStatus(self, oldStatus);
 }