Handle zombie threads in JDWP.

Mostly a matter of making DecodeThread more robust and passing JDWP::JdwpError
statuses around, but enough work that I feel justified in having left this as a
TODO for so long.

Change-Id: I779b6fcc6355dc6288355742f4b7babc531b8e38
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index cf5b722..890bc29 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -917,8 +917,9 @@
 
   VLOG(jdwp) << StringPrintf("  Req for name of thread %#llx", thread_id);
   std::string name;
-  if (!Dbg::GetThreadName(thread_id, name)) {
-    return ERR_INVALID_THREAD;
+  JdwpError error = Dbg::GetThreadName(thread_id, name);
+  if (error != ERR_NONE) {
+    return error;
   }
   VLOG(jdwp) << StringPrintf("  Name of thread %#llx is \"%s\"", thread_id, name.c_str());
   expandBufAddUtf8String(pReply, name);
@@ -975,8 +976,9 @@
 
   JDWP::JdwpThreadStatus threadStatus;
   JDWP::JdwpSuspendStatus suspendStatus;
-  if (!Dbg::GetThreadStatus(thread_id, &threadStatus, &suspendStatus)) {
-    return ERR_INVALID_THREAD;
+  JdwpError error = Dbg::GetThreadStatus(thread_id, &threadStatus, &suspendStatus);
+  if (error != ERR_NONE) {
+    return error;
   }
 
   VLOG(jdwp) << "    --> " << threadStatus << ", " << suspendStatus;
@@ -1008,15 +1010,21 @@
   uint32_t start_frame = Read4BE(&buf);
   uint32_t length = Read4BE(&buf);
 
-  if (!Dbg::ThreadExists(thread_id)) {
-    return ERR_INVALID_THREAD;
+  bool is_suspended;
+  JdwpError error = Dbg::IsSuspended(thread_id, is_suspended);
+  if (error != ERR_NONE) {
+    return error;
   }
-  if (!Dbg::IsSuspended(thread_id)) {
+  if (!is_suspended) {
     LOG(WARNING) << StringPrintf("  Rejecting req for frames in running thread %#llx", thread_id);
     return ERR_THREAD_NOT_SUSPENDED;
   }
 
-  size_t actual_frame_count = Dbg::GetThreadFrameCount(thread_id);
+  size_t actual_frame_count;
+  error = Dbg::GetThreadFrameCount(thread_id, actual_frame_count);
+  if (error != ERR_NONE) {
+    return error;
+  }
 
   VLOG(jdwp) << StringPrintf("  Request for frames: thread_id=%#llx start=%d length=%d [count=%zd]", thread_id, start_frame, length, actual_frame_count);
   if (actual_frame_count <= 0) {
@@ -1043,17 +1051,20 @@
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
 
-  if (!Dbg::ThreadExists(thread_id)) {
-    return ERR_INVALID_THREAD;
+  bool is_suspended;
+  JdwpError error = Dbg::IsSuspended(thread_id, is_suspended);
+  if (error != ERR_NONE) {
+    return error;
   }
-  if (!Dbg::IsSuspended(thread_id)) {
+  if (!is_suspended) {
     LOG(WARNING) << StringPrintf("  Rejecting req for frames in running thread %#llx", thread_id);
     return ERR_THREAD_NOT_SUSPENDED;
   }
 
-  int frame_count = Dbg::GetThreadFrameCount(thread_id);
-  if (frame_count < 0) {
-    return ERR_INVALID_THREAD;
+  size_t frame_count;
+  error = Dbg::GetThreadFrameCount(thread_id, frame_count);
+  if (error != ERR_NONE) {
+    return error;
   }
   expandBufAdd4BE(pReply, static_cast<uint32_t>(frame_count));