Fix JDWP event races

Fix a race where the JDWP connection could be closed before the VM_DEATH event
is sent during runtime shutdown.

Fix potential race where we could wait forever for the JDWP thread to establish
connection.

Bug: 16720689

Change-Id: I227e0a15a2fd17d7bfe2a66a35d719d558fcd32d
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 1cddb8b..6d2f21e 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -664,6 +664,11 @@
 }
 
 void Dbg::StopJdwp() {
+  // Post VM_DEATH event before the JDWP connection is closed (either by the JDWP thread or the
+  // destruction of gJdwpState).
+  if (gJdwpState != nullptr && gJdwpState->IsActive()) {
+    gJdwpState->PostVMDeath();
+  }
   // Prevent the JDWP thread from processing JDWP incoming packets after we close the connection.
   Disposed();
   delete gJdwpState;
diff --git a/runtime/jdwp/jdwp_main.cc b/runtime/jdwp/jdwp_main.cc
index 7795b7c..4155c82 100644
--- a/runtime/jdwp/jdwp_main.cc
+++ b/runtime/jdwp/jdwp_main.cc
@@ -283,7 +283,9 @@
     {
       ScopedThreadStateChange tsc(self, kWaitingForDebuggerToAttach);
       MutexLock attach_locker(self, state->attach_lock_);
-      state->attach_cond_.Wait(self);
+      while (state->debug_thread_id_ == 0) {
+        state->attach_cond_.Wait(self);
+      }
     }
     if (!state->IsActive()) {
       LOG(ERROR) << "JDWP connection failed";
@@ -335,10 +337,6 @@
  */
 JdwpState::~JdwpState() {
   if (netState != NULL) {
-    if (IsConnected()) {
-      PostVMDeath();
-    }
-
     /*
      * Close down the network to inspire the thread to halt.
      */
@@ -458,6 +456,7 @@
       if (!netState->Establish(options_)) {
         /* wake anybody who was waiting for us to succeed */
         MutexLock mu(thread_, attach_lock_);
+        debug_thread_id_ = static_cast<ObjectId>(-1);
         attach_cond_.Broadcast(thread_);
         break;
       }