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
(cherry picked from commit d8b3537b89fa68599534a65afc3b272639cd4a75)
Change-Id: I4b8996ade6a38fa8f7f23c3000b7184b162907d7
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;
}