Home | History | Annotate | Download | only in jdwp
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <errno.h>
     18 #include <stdlib.h>
     19 #include <sys/time.h>
     20 #include <time.h>
     21 #include <unistd.h>
     22 
     23 #include "android-base/stringprintf.h"
     24 
     25 #include "base/atomic.h"
     26 #include "base/logging.h"  // For VLOG.
     27 #include "base/time_utils.h"
     28 #include "debugger.h"
     29 #include "jdwp/jdwp_priv.h"
     30 #include "scoped_thread_state_change-inl.h"
     31 
     32 namespace art {
     33 
     34 namespace JDWP {
     35 
     36 using android::base::StringPrintf;
     37 
     38 static void* StartJdwpThread(void* arg);
     39 
     40 
     41 static bool ParseJdwpOption(const std::string& name,
     42                             const std::string& value,
     43                             JdwpOptions* jdwp_options) {
     44   if (name == "transport") {
     45     if (value == "dt_socket") {
     46       jdwp_options->transport = JDWP::kJdwpTransportSocket;
     47     } else if (value == "dt_android_adb") {
     48       jdwp_options->transport = JDWP::kJdwpTransportAndroidAdb;
     49     } else {
     50       jdwp_options->transport = JDWP::kJdwpTransportUnknown;
     51       LOG(ERROR) << "JDWP transport not supported: " << value;
     52       return false;
     53     }
     54   } else if (name == "server") {
     55     if (value == "n") {
     56       jdwp_options->server = false;
     57     } else if (value == "y") {
     58       jdwp_options->server = true;
     59     } else {
     60       LOG(ERROR) << "JDWP option 'server' must be 'y' or 'n'";
     61       return false;
     62     }
     63   } else if (name == "suspend") {
     64     if (value == "n") {
     65       jdwp_options->suspend = false;
     66     } else if (value == "y") {
     67       jdwp_options->suspend = true;
     68     } else {
     69       LOG(ERROR) << "JDWP option 'suspend' must be 'y' or 'n'";
     70       return false;
     71     }
     72   } else if (name == "address") {
     73     /* this is either <port> or <host>:<port> */
     74     std::string port_string;
     75     jdwp_options->host.clear();
     76     std::string::size_type colon = value.find(':');
     77     if (colon != std::string::npos) {
     78       jdwp_options->host = value.substr(0, colon);
     79       port_string = value.substr(colon + 1);
     80     } else {
     81       port_string = value;
     82     }
     83     if (port_string.empty()) {
     84       LOG(ERROR) << "JDWP address missing port: " << value;
     85       return false;
     86     }
     87     char* end;
     88     uint64_t port = strtoul(port_string.c_str(), &end, 10);
     89     if (*end != '\0' || port > 0xffff) {
     90       LOG(ERROR) << "JDWP address has junk in port field: " << value;
     91       return false;
     92     }
     93     jdwp_options->port = port;
     94   } else if (name == "launch" || name == "onthrow" || name == "oncaught" || name == "timeout") {
     95     /* valid but unsupported */
     96     LOG(INFO) << "Ignoring JDWP option '" << name << "'='" << value << "'";
     97   } else {
     98     LOG(INFO) << "Ignoring unrecognized JDWP option '" << name << "'='" << value << "'";
     99   }
    100 
    101   return true;
    102 }
    103 
    104 bool ParseJdwpOptions(const std::string& options, JdwpOptions* jdwp_options) {
    105   VLOG(jdwp) << "ParseJdwpOptions: " << options;
    106 
    107   if (options == "help") {
    108     LOG(ERROR) << "Example: -XjdwpOptions:transport=dt_socket,address=8000,server=y\n"
    109                << "Example: -Xrunjdwp:transport=dt_socket,address=8000,server=y\n"
    110                << "Example: -Xrunjdwp:transport=dt_socket,address=localhost:6500,server=n\n";
    111     return false;
    112   }
    113 
    114   const std::string s;
    115 
    116   std::vector<std::string> pairs;
    117   Split(options, ',', &pairs);
    118 
    119   for (const std::string& jdwp_option : pairs) {
    120     std::string::size_type equals_pos = jdwp_option.find('=');
    121     if (equals_pos == std::string::npos) {
    122       LOG(ERROR) << s << "Can't parse JDWP option '" << jdwp_option << "' in '" << options << "'";
    123       return false;
    124     }
    125 
    126     bool parse_attempt = ParseJdwpOption(jdwp_option.substr(0, equals_pos),
    127                                          jdwp_option.substr(equals_pos + 1),
    128                                          jdwp_options);
    129     if (!parse_attempt) {
    130       // We fail to parse this JDWP option.
    131       return parse_attempt;
    132     }
    133   }
    134 
    135   if (jdwp_options->transport == JDWP::kJdwpTransportUnknown) {
    136     LOG(ERROR) << s << "Must specify JDWP transport: " << options;
    137     return false;
    138   }
    139 #if ART_TARGET_ANDROID
    140   if (jdwp_options->transport == JDWP::kJdwpTransportNone) {
    141     jdwp_options->transport = JDWP::kJdwpTransportAndroidAdb;
    142     LOG(WARNING) << "no JDWP transport specified. Defaulting to dt_android_adb";
    143   }
    144 #endif
    145   if (!jdwp_options->server && (jdwp_options->host.empty() || jdwp_options->port == 0)) {
    146     LOG(ERROR) << s << "Must specify JDWP host and port when server=n: " << options;
    147     return false;
    148   }
    149 
    150   return true;
    151 }
    152 
    153 /*
    154  * JdwpNetStateBase class implementation
    155  */
    156 JdwpNetStateBase::JdwpNetStateBase(JdwpState* state)
    157     : state_(state), socket_lock_("JdwpNetStateBase lock", kJdwpSocketLock) {
    158   clientSock = -1;
    159   wake_pipe_[0] = -1;
    160   wake_pipe_[1] = -1;
    161   input_count_ = 0;
    162   awaiting_handshake_ = false;
    163 }
    164 
    165 JdwpNetStateBase::~JdwpNetStateBase() {
    166   if (wake_pipe_[0] != -1) {
    167     close(wake_pipe_[0]);
    168     wake_pipe_[0] = -1;
    169   }
    170   if (wake_pipe_[1] != -1) {
    171     close(wake_pipe_[1]);
    172     wake_pipe_[1] = -1;
    173   }
    174 }
    175 
    176 bool JdwpNetStateBase::MakePipe() {
    177   if (pipe(wake_pipe_) == -1) {
    178     PLOG(ERROR) << "pipe failed";
    179     return false;
    180   }
    181   return true;
    182 }
    183 
    184 void JdwpNetStateBase::WakePipe() {
    185   // If we might be sitting in select, kick us loose.
    186   if (wake_pipe_[1] != -1) {
    187     VLOG(jdwp) << "+++ writing to wake pipe";
    188     TEMP_FAILURE_RETRY(write(wake_pipe_[1], "", 1));
    189   }
    190 }
    191 
    192 void JdwpNetStateBase::ConsumeBytes(size_t count) {
    193   CHECK_GT(count, 0U);
    194   CHECK_LE(count, input_count_);
    195 
    196   if (count == input_count_) {
    197     input_count_ = 0;
    198     return;
    199   }
    200 
    201   memmove(input_buffer_, input_buffer_ + count, input_count_ - count);
    202   input_count_ -= count;
    203 }
    204 
    205 bool JdwpNetStateBase::HaveFullPacket() {
    206   if (awaiting_handshake_) {
    207     return (input_count_ >= kMagicHandshakeLen);
    208   }
    209   if (input_count_ < 4) {
    210     return false;
    211   }
    212   uint32_t length = Get4BE(input_buffer_);
    213   return (input_count_ >= length);
    214 }
    215 
    216 bool JdwpNetStateBase::IsAwaitingHandshake() {
    217   return awaiting_handshake_;
    218 }
    219 
    220 void JdwpNetStateBase::SetAwaitingHandshake(bool new_state) {
    221   awaiting_handshake_ = new_state;
    222 }
    223 
    224 bool JdwpNetStateBase::IsConnected() {
    225   return clientSock >= 0;
    226 }
    227 
    228 // Close a connection from a debugger (which may have already dropped us).
    229 // Resets the state so we're ready to receive a new connection.
    230 // Only called from the JDWP thread.
    231 void JdwpNetStateBase::Close() {
    232   if (clientSock < 0) {
    233     return;
    234   }
    235 
    236   VLOG(jdwp) << "+++ closing JDWP connection on fd " << clientSock;
    237 
    238   close(clientSock);
    239   clientSock = -1;
    240 }
    241 
    242 /*
    243  * Write a packet of "length" bytes. Grabs a mutex to assure atomicity.
    244  */
    245 ssize_t JdwpNetStateBase::WritePacket(ExpandBuf* pReply, size_t length) {
    246   DCHECK_LE(length, expandBufGetLength(pReply));
    247   if (!IsConnected()) {
    248     LOG(WARNING) << "Connection with debugger is closed";
    249     return -1;
    250   }
    251   MutexLock mu(Thread::Current(), socket_lock_);
    252   return TEMP_FAILURE_RETRY(write(clientSock, expandBufGetBuffer(pReply), length));
    253 }
    254 
    255 /*
    256  * Write a buffered packet. Grabs a mutex to assure atomicity.
    257  */
    258 ssize_t JdwpNetStateBase::WriteBufferedPacket(const std::vector<iovec>& iov) {
    259   MutexLock mu(Thread::Current(), socket_lock_);
    260   return WriteBufferedPacketLocked(iov);
    261 }
    262 
    263 ssize_t JdwpNetStateBase::WriteBufferedPacketLocked(const std::vector<iovec>& iov) {
    264   socket_lock_.AssertHeld(Thread::Current());
    265   DCHECK(IsConnected()) << "Connection with debugger is closed";
    266   return TEMP_FAILURE_RETRY(writev(clientSock, &iov[0], iov.size()));
    267 }
    268 
    269 bool JdwpState::IsConnected() {
    270   return netState != nullptr && netState->IsConnected();
    271 }
    272 
    273 void JdwpState::SendBufferedRequest(uint32_t type, const std::vector<iovec>& iov) {
    274   if (!IsConnected()) {
    275     // Can happen with some DDMS events.
    276     VLOG(jdwp) << "Not sending JDWP packet: no debugger attached!";
    277     return;
    278   }
    279 
    280   size_t expected = 0;
    281   for (size_t i = 0; i < iov.size(); ++i) {
    282     expected += iov[i].iov_len;
    283   }
    284 
    285   errno = 0;
    286   ssize_t actual = netState->WriteBufferedPacket(iov);
    287   if (static_cast<size_t>(actual) != expected) {
    288     PLOG(ERROR) << StringPrintf("Failed to send JDWP packet %c%c%c%c to debugger (%zd of %zu)",
    289                                 static_cast<char>(type >> 24),
    290                                 static_cast<char>(type >> 16),
    291                                 static_cast<char>(type >> 8),
    292                                 static_cast<char>(type),
    293                                 actual, expected);
    294   }
    295 }
    296 
    297 void JdwpState::SendRequest(ExpandBuf* pReq) {
    298   if (!IsConnected()) {
    299     // Can happen with some DDMS events.
    300     VLOG(jdwp) << "Not sending JDWP packet: no debugger attached!";
    301     return;
    302   }
    303 
    304   errno = 0;
    305   ssize_t actual = netState->WritePacket(pReq, expandBufGetLength(pReq));
    306   if (static_cast<size_t>(actual) != expandBufGetLength(pReq)) {
    307     PLOG(ERROR) << StringPrintf("Failed to send JDWP packet to debugger (%zd of %zu)",
    308                                 actual, expandBufGetLength(pReq));
    309   }
    310 }
    311 
    312 /*
    313  * Get the next "request" serial number.  We use this when sending
    314  * packets to the debugger.
    315  */
    316 uint32_t JdwpState::NextRequestSerial() {
    317   return request_serial_++;
    318 }
    319 
    320 /*
    321  * Get the next "event" serial number.  We use this in the response to
    322  * message type EventRequest.Set.
    323  */
    324 uint32_t JdwpState::NextEventSerial() {
    325   return event_serial_++;
    326 }
    327 
    328 JdwpState::JdwpState(const JdwpOptions* options)
    329     : options_(options),
    330       thread_start_lock_("JDWP thread start lock", kJdwpStartLock),
    331       thread_start_cond_("JDWP thread start condition variable", thread_start_lock_),
    332       pthread_(0),
    333       thread_(nullptr),
    334       debug_thread_started_(false),
    335       debug_thread_id_(0),
    336       run(false),
    337       netState(nullptr),
    338       attach_lock_("JDWP attach lock", kJdwpAttachLock),
    339       attach_cond_("JDWP attach condition variable", attach_lock_),
    340       last_activity_time_ms_(0),
    341       request_serial_(0x10000000),
    342       event_serial_(0x20000000),
    343       event_list_lock_("JDWP event list lock", kJdwpEventListLock),
    344       event_list_(nullptr),
    345       event_list_size_(0),
    346       jdwp_token_lock_("JDWP token lock"),
    347       jdwp_token_cond_("JDWP token condition variable", jdwp_token_lock_),
    348       jdwp_token_owner_thread_id_(0),
    349       ddm_is_active_(false),
    350       should_exit_(false),
    351       exit_status_(0),
    352       shutdown_lock_("JDWP shutdown lock", kJdwpShutdownLock),
    353       shutdown_cond_("JDWP shutdown condition variable", shutdown_lock_),
    354       processing_request_(false) {
    355   Locks::AddToExpectedMutexesOnWeakRefAccess(&event_list_lock_);
    356 }
    357 
    358 /*
    359  * Initialize JDWP.
    360  *
    361  * Does not return until JDWP thread is running, but may return before
    362  * the thread is accepting network connections.
    363  */
    364 JdwpState* JdwpState::Create(const JdwpOptions* options) {
    365   Thread* self = Thread::Current();
    366   Locks::mutator_lock_->AssertNotHeld(self);
    367   std::unique_ptr<JdwpState> state(new JdwpState(options));
    368   switch (options->transport) {
    369     case kJdwpTransportSocket:
    370       InitSocketTransport(state.get(), options);
    371       break;
    372 #ifdef ART_TARGET_ANDROID
    373     case kJdwpTransportAndroidAdb:
    374       InitAdbTransport(state.get(), options);
    375       break;
    376 #endif
    377     default:
    378       LOG(FATAL) << "Unknown transport: " << options->transport;
    379   }
    380   {
    381     /*
    382      * Grab a mutex before starting the thread.  This ensures they
    383      * won't signal the cond var before we're waiting.
    384      */
    385     state->thread_start_lock_.AssertNotHeld(self);
    386     MutexLock thread_start_locker(self, state->thread_start_lock_);
    387 
    388     /*
    389      * We have bound to a port, or are trying to connect outbound to a
    390      * debugger.  Create the JDWP thread and let it continue the mission.
    391      */
    392     CHECK_PTHREAD_CALL(pthread_create, (&state->pthread_, nullptr, StartJdwpThread, state.get()),
    393                        "JDWP thread");
    394 
    395     /*
    396      * Wait until the thread finishes basic initialization.
    397      */
    398     while (!state->debug_thread_started_) {
    399       state->thread_start_cond_.Wait(self);
    400     }
    401   }
    402 
    403   if (options->suspend) {
    404     /*
    405      * For suspend=y, wait for the debugger to connect to us or for us to
    406      * connect to the debugger.
    407      *
    408      * The JDWP thread will signal us when it connects successfully or
    409      * times out (for timeout=xxx), so we have to check to see what happened
    410      * when we wake up.
    411      */
    412     {
    413       ScopedThreadStateChange tsc(self, kWaitingForDebuggerToAttach);
    414       MutexLock attach_locker(self, state->attach_lock_);
    415       while (state->debug_thread_id_ == 0) {
    416         state->attach_cond_.Wait(self);
    417       }
    418     }
    419     if (!state->IsActive()) {
    420       LOG(ERROR) << "JDWP connection failed";
    421       return nullptr;
    422     }
    423 
    424     LOG(INFO) << "JDWP connected";
    425 
    426     /*
    427      * Ordinarily we would pause briefly to allow the debugger to set
    428      * breakpoints and so on, but for "suspend=y" the VM init code will
    429      * pause the VM when it sends the VM_START message.
    430      */
    431   }
    432 
    433   return state.release();
    434 }
    435 
    436 /*
    437  * Reset all session-related state.  There should not be an active connection
    438  * to the client at this point.  The rest of the VM still thinks there is
    439  * a debugger attached.
    440  *
    441  * This includes freeing up the debugger event list.
    442  */
    443 void JdwpState::ResetState() {
    444   /* could reset the serial numbers, but no need to */
    445 
    446   UnregisterAll();
    447   {
    448     MutexLock mu(Thread::Current(), event_list_lock_);
    449     CHECK(event_list_ == nullptr);
    450   }
    451 
    452   /*
    453    * Should not have one of these in progress.  If the debugger went away
    454    * mid-request, though, we could see this.
    455    */
    456   if (jdwp_token_owner_thread_id_ != 0) {
    457     LOG(WARNING) << "Resetting state while event in progress";
    458     DCHECK(false);
    459   }
    460 }
    461 
    462 /*
    463  * Tell the JDWP thread to shut down.  Frees "state".
    464  */
    465 JdwpState::~JdwpState() {
    466   if (netState != nullptr) {
    467     /*
    468      * Close down the network to inspire the thread to halt. If a request is being processed,
    469      * we need to wait for it to finish first.
    470      */
    471     {
    472       Thread* self = Thread::Current();
    473       MutexLock mu(self, shutdown_lock_);
    474       while (processing_request_) {
    475         VLOG(jdwp) << "JDWP command in progress: wait for it to finish ...";
    476         shutdown_cond_.Wait(self);
    477       }
    478 
    479       VLOG(jdwp) << "JDWP shutting down net...";
    480       netState->Shutdown();
    481     }
    482 
    483     if (debug_thread_started_) {
    484       run = false;
    485       void* threadReturn;
    486       if (pthread_join(pthread_, &threadReturn) != 0) {
    487         LOG(WARNING) << "JDWP thread join failed";
    488       }
    489     }
    490 
    491     VLOG(jdwp) << "JDWP freeing netstate...";
    492     delete netState;
    493     netState = nullptr;
    494   }
    495   CHECK(netState == nullptr);
    496 
    497   ResetState();
    498 
    499   Locks::RemoveFromExpectedMutexesOnWeakRefAccess(&event_list_lock_);
    500 }
    501 
    502 /*
    503  * Are we talking to a debugger?
    504  */
    505 bool JdwpState::IsActive() {
    506   return IsConnected();
    507 }
    508 
    509 // Returns "false" if we encounter a connection-fatal error.
    510 bool JdwpState::HandlePacket() {
    511   Thread* const self = Thread::Current();
    512   {
    513     MutexLock mu(self, shutdown_lock_);
    514     processing_request_ = true;
    515   }
    516   JdwpNetStateBase* netStateBase = netState;
    517   CHECK(netStateBase != nullptr) << "Connection has been closed";
    518   JDWP::Request request(netStateBase->input_buffer_, netStateBase->input_count_);
    519 
    520   ExpandBuf* pReply = expandBufAlloc();
    521   bool skip_reply = false;
    522   size_t replyLength = ProcessRequest(&request, pReply, &skip_reply);
    523   ssize_t cc = 0;
    524   if (!skip_reply) {
    525     cc = netStateBase->WritePacket(pReply, replyLength);
    526   } else {
    527     DCHECK_EQ(replyLength, 0U);
    528   }
    529   expandBufFree(pReply);
    530 
    531   /*
    532    * We processed this request and sent its reply so we can release the JDWP token.
    533    */
    534   ReleaseJdwpTokenForCommand();
    535 
    536   if (cc != static_cast<ssize_t>(replyLength)) {
    537     PLOG(ERROR) << "Failed sending reply to debugger";
    538     return false;
    539   }
    540   netStateBase->ConsumeBytes(request.GetLength());
    541   {
    542     MutexLock mu(self, shutdown_lock_);
    543     processing_request_ = false;
    544     shutdown_cond_.Broadcast(self);
    545   }
    546   return true;
    547 }
    548 
    549 /*
    550  * Entry point for JDWP thread.  The thread was created through the VM
    551  * mechanisms, so there is a java/lang/Thread associated with us.
    552  */
    553 static void* StartJdwpThread(void* arg) {
    554   JdwpState* state = reinterpret_cast<JdwpState*>(arg);
    555   CHECK(state != nullptr);
    556 
    557   state->Run();
    558   return nullptr;
    559 }
    560 
    561 void JdwpState::Run() {
    562   Runtime* runtime = Runtime::Current();
    563   CHECK(runtime->AttachCurrentThread("JDWP", true, runtime->GetSystemThreadGroup(),
    564                                      !runtime->IsAotCompiler()));
    565 
    566   VLOG(jdwp) << "JDWP: thread running";
    567 
    568   /*
    569    * Finish initializing, then notify the creating thread that
    570    * we're running.
    571    */
    572   thread_ = Thread::Current();
    573   run = true;
    574 
    575   {
    576     MutexLock locker(thread_, thread_start_lock_);
    577     debug_thread_started_ = true;
    578     thread_start_cond_.Broadcast(thread_);
    579   }
    580 
    581   /* set the thread state to kWaitingInMainDebuggerLoop so GCs don't wait for us */
    582   CHECK_EQ(thread_->GetState(), kNative);
    583   Locks::mutator_lock_->AssertNotHeld(thread_);
    584   thread_->SetState(kWaitingInMainDebuggerLoop);
    585 
    586   /*
    587    * Loop forever if we're in server mode, processing connections.  In
    588    * non-server mode, we bail out of the thread when the debugger drops
    589    * us.
    590    *
    591    * We broadcast a notification when a debugger attaches, after we
    592    * successfully process the handshake.
    593    */
    594   while (run) {
    595     if (options_->server) {
    596       /*
    597        * Block forever, waiting for a connection.  To support the
    598        * "timeout=xxx" option we'll need to tweak this.
    599        */
    600       if (!netState->Accept()) {
    601         break;
    602       }
    603     } else {
    604       /*
    605        * If we're not acting as a server, we need to connect out to the
    606        * debugger.  To support the "timeout=xxx" option we need to
    607        * have a timeout if the handshake reply isn't received in a
    608        * reasonable amount of time.
    609        */
    610       if (!netState->Establish(options_)) {
    611         /* wake anybody who was waiting for us to succeed */
    612         MutexLock mu(thread_, attach_lock_);
    613         debug_thread_id_ = static_cast<ObjectId>(-1);
    614         attach_cond_.Broadcast(thread_);
    615         break;
    616       }
    617     }
    618 
    619     /* prep debug code to handle the new connection */
    620     Dbg::Connected();
    621 
    622     /* process requests until the debugger drops */
    623     bool first = true;
    624     while (!Dbg::IsDisposed()) {
    625       // sanity check -- shouldn't happen?
    626       CHECK_EQ(thread_->GetState(), kWaitingInMainDebuggerLoop);
    627 
    628       if (!netState->ProcessIncoming()) {
    629         /* blocking read */
    630         break;
    631       }
    632 
    633       if (should_exit_) {
    634         exit(exit_status_);
    635       }
    636 
    637       if (first && !netState->IsAwaitingHandshake()) {
    638         /* handshake worked, tell the interpreter that we're active */
    639         first = false;
    640 
    641         /* set thread ID; requires object registry to be active */
    642         {
    643           ScopedObjectAccess soa(thread_);
    644           debug_thread_id_ = Dbg::GetThreadSelfId();
    645         }
    646 
    647         /* wake anybody who's waiting for us */
    648         MutexLock mu(thread_, attach_lock_);
    649         attach_cond_.Broadcast(thread_);
    650       }
    651     }
    652 
    653     netState->Close();
    654 
    655     if (ddm_is_active_) {
    656       ddm_is_active_ = false;
    657 
    658       /* broadcast the disconnect; must be in RUNNING state */
    659       ScopedObjectAccess soa(thread_);
    660       Dbg::DdmDisconnected();
    661     }
    662 
    663     {
    664       ScopedObjectAccess soa(thread_);
    665 
    666       // Release session state, e.g. remove breakpoint instructions.
    667       ResetState();
    668     }
    669     // Tell the rest of the runtime that the debugger is no longer around.
    670     Dbg::Disconnected();
    671 
    672     /* if we had threads suspended, resume them now */
    673     Dbg::UndoDebuggerSuspensions();
    674 
    675     /* if we connected out, this was a one-shot deal */
    676     if (!options_->server) {
    677       run = false;
    678     }
    679   }
    680 
    681   /* back to native, for thread shutdown */
    682   CHECK_EQ(thread_->GetState(), kWaitingInMainDebuggerLoop);
    683   thread_->SetState(kNative);
    684 
    685   VLOG(jdwp) << "JDWP: thread detaching and exiting...";
    686   runtime->DetachCurrentThread();
    687 }
    688 
    689 void JdwpState::NotifyDdmsActive() {
    690   if (!ddm_is_active_) {
    691     ddm_is_active_ = true;
    692     Dbg::DdmConnected();
    693   }
    694 }
    695 
    696 Thread* JdwpState::GetDebugThread() {
    697   return thread_;
    698 }
    699 
    700 /*
    701  * Support routines for waitForDebugger().
    702  *
    703  * We can't have a trivial "waitForDebugger" function that returns the
    704  * instant the debugger connects, because we run the risk of executing code
    705  * before the debugger has had a chance to configure breakpoints or issue
    706  * suspend calls.  It would be nice to just sit in the suspended state, but
    707  * most debuggers don't expect any threads to be suspended when they attach.
    708  *
    709  * There's no JDWP event we can post to tell the debugger, "we've stopped,
    710  * and we like it that way".  We could send a fake breakpoint, which should
    711  * cause the debugger to immediately send a resume, but the debugger might
    712  * send the resume immediately or might throw an exception of its own upon
    713  * receiving a breakpoint event that it didn't ask for.
    714  *
    715  * What we really want is a "wait until the debugger is done configuring
    716  * stuff" event.  We can approximate this with a "wait until the debugger
    717  * has been idle for a brief period".
    718  */
    719 
    720 /*
    721  * Return the time, in milliseconds, since the last debugger activity.
    722  *
    723  * Returns -1 if no debugger is attached, or 0 if we're in the middle of
    724  * processing a debugger request.
    725  */
    726 int64_t JdwpState::LastDebuggerActivity() {
    727   if (!Dbg::IsDebuggerActive()) {
    728     LOG(WARNING) << "no active debugger";
    729     return -1;
    730   }
    731 
    732   int64_t last = last_activity_time_ms_.LoadSequentiallyConsistent();
    733 
    734   /* initializing or in the middle of something? */
    735   if (last == 0) {
    736     VLOG(jdwp) << "+++ last=busy";
    737     return 0;
    738   }
    739 
    740   /* now get the current time */
    741   int64_t now = MilliTime();
    742   CHECK_GE(now, last);
    743 
    744   VLOG(jdwp) << "+++ debugger interval=" << (now - last);
    745   return now - last;
    746 }
    747 
    748 void JdwpState::ExitAfterReplying(int exit_status) {
    749   LOG(WARNING) << "Debugger told VM to exit with status " << exit_status;
    750   should_exit_ = true;
    751   exit_status_ = exit_status;
    752 }
    753 
    754 std::ostream& operator<<(std::ostream& os, const JdwpLocation& rhs) {
    755   os << "JdwpLocation["
    756      << Dbg::GetClassName(rhs.class_id) << "." << Dbg::GetMethodName(rhs.method_id)
    757      << "@" << StringPrintf("%#" PRIx64, rhs.dex_pc) << " " << rhs.type_tag << "]";
    758   return os;
    759 }
    760 
    761 bool operator==(const JdwpLocation& lhs, const JdwpLocation& rhs) {
    762   return lhs.dex_pc == rhs.dex_pc && lhs.method_id == rhs.method_id &&
    763       lhs.class_id == rhs.class_id && lhs.type_tag == rhs.type_tag;
    764 }
    765 
    766 bool operator!=(const JdwpLocation& lhs, const JdwpLocation& rhs) {
    767   return !(lhs == rhs);
    768 }
    769 
    770 bool operator==(const JdwpOptions& lhs, const JdwpOptions& rhs) {
    771   if (&lhs == &rhs) {
    772     return true;
    773   }
    774 
    775   return lhs.transport == rhs.transport &&
    776       lhs.server == rhs.server &&
    777       lhs.suspend == rhs.suspend &&
    778       lhs.host == rhs.host &&
    779       lhs.port == rhs.port;
    780 }
    781 
    782 }  // namespace JDWP
    783 
    784 }  // namespace art
    785