}
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;
{
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";
*/
JdwpState::~JdwpState() {
if (netState != NULL) {
- if (IsConnected()) {
- PostVMDeath();
- }
-
/*
* Close down the network to inspire the thread to halt.
*/
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;
}