summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2014-02-18 14:16:00 +0100
committerSebastien Hertz <shertz@google.com>2014-02-19 09:10:40 +0000
commit21e729c7859ce7909e85d135f6c9e32bbba38860 (patch)
tree6cb11d1db4e19d4e68a55960e862d7304a41f05a /runtime
parent2c3458dbda97b70158ee7ef22d13ce473a2a2147 (diff)
downloadart-21e729c7859ce7909e85d135f6c9e32bbba38860.zip
art-21e729c7859ce7909e85d135f6c9e32bbba38860.tar.gz
art-21e729c7859ce7909e85d135f6c9e32bbba38860.tar.bz2
Fix failing check during JDWP invoke.
Fixes a race where the JDWP thread expects the invoke thread can be suspended (suspend_count != 0) before invoke thread actually updates its suspend count. It happens after the invoke thread signals the JDWP thread to notify invoke is completed but before incrementing its suspend count. In the meantime, the JDWP thread wakes up and checks whether invoke thread has updated its supend count. But there is no way to prevent the JDWP thread to do so before the invoke thread updates its suspend count. We now move the invoke completion code after the suspend count update. Then the JDWP thread wakes up at the right time. Bug: 11247837 Bug: 12578041 Change-Id: Ib6079c6e330671b34217838e26b1e758706d3da6
Diffstat (limited to 'runtime')
-rw-r--r--runtime/jdwp/jdwp_event.cc8
-rw-r--r--runtime/thread_list.cc12
2 files changed, 12 insertions, 8 deletions
diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc
index e372c26..677b04b 100644
--- a/runtime/jdwp/jdwp_event.cc
+++ b/runtime/jdwp/jdwp_event.cc
@@ -576,14 +576,6 @@ void JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId
Dbg::ExecuteMethod(pReq);
pReq->error = ERR_NONE;
-
- /* clear this before signaling */
- pReq->invoke_needed = false;
-
- VLOG(jdwp) << "invoke complete, signaling and self-suspending";
- Thread* self = Thread::Current();
- MutexLock mu(self, pReq->lock);
- pReq->cond.Signal(self);
}
}
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 25f692d..9f67c96 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -577,6 +577,18 @@ void ThreadList::SuspendSelfForDebugger() {
VLOG(threads) << *self << " self-suspending (debugger)";
+ // Tell JDWP we've completed invocation and are ready to suspend.
+ DebugInvokeReq* pReq = self->GetInvokeReq();
+ DCHECK(pReq != NULL);
+ if (pReq->invoke_needed) {
+ // Clear this before signaling.
+ pReq->invoke_needed = false;
+
+ VLOG(jdwp) << "invoke complete, signaling";
+ MutexLock mu(self, pReq->lock);
+ pReq->cond.Signal(self);
+ }
+
// Tell JDWP that we've completed suspension. The JDWP thread can't
// tell us to resume before we're fully asleep because we hold the
// suspend count lock.