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 "atomic.h"
     24 #include "base/logging.h"
     25 #include "debugger.h"
     26 #include "jdwp/jdwp_priv.h"
     27 #include "scoped_thread_state_change.h"
     28 
     29 namespace art {
     30 
     31 namespace JDWP {
     32 
     33 static void* StartJdwpThread(void* arg);
     34 
     35 /*
     36  * JdwpNetStateBase class implementation
     37  */
     38 JdwpNetStateBase::JdwpNetStateBase(JdwpState* state)
     39     : state_(state), socket_lock_("JdwpNetStateBase lock", kJdwpSocketLock) {
     40   clientSock = -1;
     41   wake_pipe_[0] = -1;
     42   wake_pipe_[1] = -1;
     43   input_count_ = 0;
     44   awaiting_handshake_ = false;
     45 }
     46 
     47 JdwpNetStateBase::~JdwpNetStateBase() {
     48   if (wake_pipe_[0] != -1) {
     49     close(wake_pipe_[0]);
     50     wake_pipe_[0] = -1;
     51   }
     52   if (wake_pipe_[1] != -1) {
     53     close(wake_pipe_[1]);
     54     wake_pipe_[1] = -1;
     55   }
     56 }
     57 
     58 bool JdwpNetStateBase::MakePipe() {
     59   if (pipe(wake_pipe_) == -1) {
     60     PLOG(ERROR) << "pipe failed";
     61     return false;
     62   }
     63   return true;
     64 }
     65 
     66 void JdwpNetStateBase::WakePipe() {
     67   // If we might be sitting in select, kick us loose.
     68   if (wake_pipe_[1] != -1) {
     69     VLOG(jdwp) << "+++ writing to wake pipe";
     70     TEMP_FAILURE_RETRY(write(wake_pipe_[1], "", 1));
     71   }
     72 }
     73 
     74 void JdwpNetStateBase::ConsumeBytes(size_t count) {
     75   CHECK_GT(count, 0U);
     76   CHECK_LE(count, input_count_);
     77 
     78   if (count == input_count_) {
     79     input_count_ = 0;
     80     return;
     81   }
     82 
     83   memmove(input_buffer_, input_buffer_ + count, input_count_ - count);
     84   input_count_ -= count;
     85 }
     86 
     87 bool JdwpNetStateBase::HaveFullPacket() {
     88   if (awaiting_handshake_) {
     89     return (input_count_ >= kMagicHandshakeLen);
     90   }
     91   if (input_count_ < 4) {
     92     return false;
     93   }
     94   uint32_t length = Get4BE(input_buffer_);
     95   return (input_count_ >= length);
     96 }
     97 
     98 bool JdwpNetStateBase::IsAwaitingHandshake() {
     99   return awaiting_handshake_;
    100 }
    101 
    102 void JdwpNetStateBase::SetAwaitingHandshake(bool new_state) {
    103   awaiting_handshake_ = new_state;
    104 }
    105 
    106 bool JdwpNetStateBase::IsConnected() {
    107   return clientSock >= 0;
    108 }
    109 
    110 // Close a connection from a debugger (which may have already dropped us).
    111 // Resets the state so we're ready to receive a new connection.
    112 // Only called from the JDWP thread.
    113 void JdwpNetStateBase::Close() {
    114   if (clientSock < 0) {
    115     return;
    116   }
    117 
    118   VLOG(jdwp) << "+++ closing JDWP connection on fd " << clientSock;
    119 
    120   close(clientSock);
    121   clientSock = -1;
    122 }
    123 
    124 /*
    125  * Write a packet of "length" bytes. Grabs a mutex to assure atomicity.
    126  */
    127 ssize_t JdwpNetStateBase::WritePacket(ExpandBuf* pReply, size_t length) {
    128   MutexLock mu(Thread::Current(), socket_lock_);
    129   DCHECK_LE(length, expandBufGetLength(pReply));
    130   return TEMP_FAILURE_RETRY(write(clientSock, expandBufGetBuffer(pReply), length));
    131 }
    132 
    133 /*
    134  * Write a buffered packet. Grabs a mutex to assure atomicity.
    135  */
    136 ssize_t JdwpNetStateBase::WriteBufferedPacket(const std::vector<iovec>& iov) {
    137   MutexLock mu(Thread::Current(), socket_lock_);
    138   return TEMP_FAILURE_RETRY(writev(clientSock, &iov[0], iov.size()));
    139 }
    140 
    141 bool JdwpState::IsConnected() {
    142   return netState != NULL && netState->IsConnected();
    143 }
    144 
    145 void JdwpState::SendBufferedRequest(uint32_t type, const std::vector<iovec>& iov) {
    146   if (!IsConnected()) {
    147     // Can happen with some DDMS events.
    148     VLOG(jdwp) << "Not sending JDWP packet: no debugger attached!";
    149     return;
    150   }
    151 
    152   size_t expected = 0;
    153   for (size_t i = 0; i < iov.size(); ++i) {
    154     expected += iov[i].iov_len;
    155   }
    156 
    157   errno = 0;
    158   ssize_t actual = netState->WriteBufferedPacket(iov);
    159   if (static_cast<size_t>(actual) != expected) {
    160     PLOG(ERROR) << StringPrintf("Failed to send JDWP packet %c%c%c%c to debugger (%zd of %zu)",
    161                                 static_cast<char>(type >> 24),
    162                                 static_cast<char>(type >> 16),
    163                                 static_cast<char>(type >> 8),
    164                                 static_cast<char>(type),
    165                                 actual, expected);
    166   }
    167 }
    168 
    169 void JdwpState::SendRequest(ExpandBuf* pReq) {
    170   if (!IsConnected()) {
    171     // Can happen with some DDMS events.
    172     VLOG(jdwp) << "Not sending JDWP packet: no debugger attached!";
    173     return;
    174   }
    175 
    176   errno = 0;
    177   ssize_t actual = netState->WritePacket(pReq, expandBufGetLength(pReq));
    178   if (static_cast<size_t>(actual) != expandBufGetLength(pReq)) {
    179     PLOG(ERROR) << StringPrintf("Failed to send JDWP packet to debugger (%zd of %zu)",
    180                                 actual, expandBufGetLength(pReq));
    181   }
    182 }
    183 
    184 /*
    185  * Get the next "request" serial number.  We use this when sending
    186  * packets to the debugger.
    187  */
    188 uint32_t JdwpState::NextRequestSerial() {
    189   return request_serial_++;
    190 }
    191 
    192 /*
    193  * Get the next "event" serial number.  We use this in the response to
    194  * message type EventRequest.Set.
    195  */
    196 uint32_t JdwpState::NextEventSerial() {
    197   return event_serial_++;
    198 }
    199 
    200 JdwpState::JdwpState(const JdwpOptions* options)
    201     : options_(options),
    202       thread_start_lock_("JDWP thread start lock", kJdwpStartLock),
    203       thread_start_cond_("JDWP thread start condition variable", thread_start_lock_),
    204       pthread_(0),
    205       thread_(NULL),
    206       debug_thread_started_(false),
    207       debug_thread_id_(0),
    208       run(false),
    209       netState(NULL),
    210       attach_lock_("JDWP attach lock", kJdwpAttachLock),
    211       attach_cond_("JDWP attach condition variable", attach_lock_),
    212       last_activity_time_ms_(0),
    213       request_serial_(0x10000000),
    214       event_serial_(0x20000000),
    215       event_list_lock_("JDWP event list lock", kJdwpEventListLock),
    216       event_list_(NULL),
    217       event_list_size_(0),
    218       event_thread_lock_("JDWP event thread lock"),
    219       event_thread_cond_("JDWP event thread condition variable", event_thread_lock_),
    220       event_thread_id_(0),
    221       process_request_lock_("JDWP process request lock"),
    222       process_request_cond_("JDWP process request condition variable", process_request_lock_),
    223       processing_request_(false),
    224       ddm_is_active_(false),
    225       should_exit_(false),
    226       exit_status_(0) {
    227 }
    228 
    229 /*
    230  * Initialize JDWP.
    231  *
    232  * Does not return until JDWP thread is running, but may return before
    233  * the thread is accepting network connections.
    234  */
    235 JdwpState* JdwpState::Create(const JdwpOptions* options) {
    236   Thread* self = Thread::Current();
    237   Locks::mutator_lock_->AssertNotHeld(self);
    238   std::unique_ptr<JdwpState> state(new JdwpState(options));
    239   switch (options->transport) {
    240     case kJdwpTransportSocket:
    241       InitSocketTransport(state.get(), options);
    242       break;
    243 #ifdef HAVE_ANDROID_OS
    244     case kJdwpTransportAndroidAdb:
    245       InitAdbTransport(state.get(), options);
    246       break;
    247 #endif
    248     default:
    249       LOG(FATAL) << "Unknown transport: " << options->transport;
    250   }
    251 
    252   {
    253     /*
    254      * Grab a mutex before starting the thread.  This ensures they
    255      * won't signal the cond var before we're waiting.
    256      */
    257     MutexLock thread_start_locker(self, state->thread_start_lock_);
    258 
    259     /*
    260      * We have bound to a port, or are trying to connect outbound to a
    261      * debugger.  Create the JDWP thread and let it continue the mission.
    262      */
    263     CHECK_PTHREAD_CALL(pthread_create, (&state->pthread_, nullptr, StartJdwpThread, state.get()),
    264                        "JDWP thread");
    265 
    266     /*
    267      * Wait until the thread finishes basic initialization.
    268      */
    269     while (!state->debug_thread_started_) {
    270       state->thread_start_cond_.Wait(self);
    271     }
    272   }
    273 
    274   if (options->suspend) {
    275     /*
    276      * For suspend=y, wait for the debugger to connect to us or for us to
    277      * connect to the debugger.
    278      *
    279      * The JDWP thread will signal us when it connects successfully or
    280      * times out (for timeout=xxx), so we have to check to see what happened
    281      * when we wake up.
    282      */
    283     {
    284       ScopedThreadStateChange tsc(self, kWaitingForDebuggerToAttach);
    285       MutexLock attach_locker(self, state->attach_lock_);
    286       while (state->debug_thread_id_ == 0) {
    287         state->attach_cond_.Wait(self);
    288       }
    289     }
    290     if (!state->IsActive()) {
    291       LOG(ERROR) << "JDWP connection failed";
    292       return NULL;
    293     }
    294 
    295     LOG(INFO) << "JDWP connected";
    296 
    297     /*
    298      * Ordinarily we would pause briefly to allow the debugger to set
    299      * breakpoints and so on, but for "suspend=y" the VM init code will
    300      * pause the VM when it sends the VM_START message.
    301      */
    302   }
    303 
    304   return state.release();
    305 }
    306 
    307 /*
    308  * Reset all session-related state.  There should not be an active connection
    309  * to the client at this point.  The rest of the VM still thinks there is
    310  * a debugger attached.
    311  *
    312  * This includes freeing up the debugger event list.
    313  */
    314 void JdwpState::ResetState() {
    315   /* could reset the serial numbers, but no need to */
    316 
    317   UnregisterAll();
    318   {
    319     MutexLock mu(Thread::Current(), event_list_lock_);
    320     CHECK(event_list_ == NULL);
    321   }
    322 
    323   Dbg::ProcessDelayedFullUndeoptimizations();
    324 
    325   /*
    326    * Should not have one of these in progress.  If the debugger went away
    327    * mid-request, though, we could see this.
    328    */
    329   if (event_thread_id_ != 0) {
    330     LOG(WARNING) << "Resetting state while event in progress";
    331     DCHECK(false);
    332   }
    333 }
    334 
    335 /*
    336  * Tell the JDWP thread to shut down.  Frees "state".
    337  */
    338 JdwpState::~JdwpState() {
    339   if (netState != NULL) {
    340     /*
    341      * Close down the network to inspire the thread to halt.
    342      */
    343     VLOG(jdwp) << "JDWP shutting down net...";
    344     netState->Shutdown();
    345 
    346     if (debug_thread_started_) {
    347       run = false;
    348       void* threadReturn;
    349       if (pthread_join(pthread_, &threadReturn) != 0) {
    350         LOG(WARNING) << "JDWP thread join failed";
    351       }
    352     }
    353 
    354     VLOG(jdwp) << "JDWP freeing netstate...";
    355     delete netState;
    356     netState = NULL;
    357   }
    358   CHECK(netState == NULL);
    359 
    360   ResetState();
    361 }
    362 
    363 /*
    364  * Are we talking to a debugger?
    365  */
    366 bool JdwpState::IsActive() {
    367   return IsConnected();
    368 }
    369 
    370 // Returns "false" if we encounter a connection-fatal error.
    371 bool JdwpState::HandlePacket() {
    372   JdwpNetStateBase* netStateBase = reinterpret_cast<JdwpNetStateBase*>(netState);
    373   JDWP::Request request(netStateBase->input_buffer_, netStateBase->input_count_);
    374 
    375   ExpandBuf* pReply = expandBufAlloc();
    376   size_t replyLength = ProcessRequest(request, pReply);
    377   ssize_t cc = netStateBase->WritePacket(pReply, replyLength);
    378 
    379   /*
    380    * We processed this request and sent its reply. Notify other threads waiting for us they can now
    381    * send events.
    382    */
    383   EndProcessingRequest();
    384 
    385   if (cc != static_cast<ssize_t>(replyLength)) {
    386     PLOG(ERROR) << "Failed sending reply to debugger";
    387     expandBufFree(pReply);
    388     return false;
    389   }
    390   expandBufFree(pReply);
    391   netStateBase->ConsumeBytes(request.GetLength());
    392   return true;
    393 }
    394 
    395 /*
    396  * Entry point for JDWP thread.  The thread was created through the VM
    397  * mechanisms, so there is a java/lang/Thread associated with us.
    398  */
    399 static void* StartJdwpThread(void* arg) {
    400   JdwpState* state = reinterpret_cast<JdwpState*>(arg);
    401   CHECK(state != NULL);
    402 
    403   state->Run();
    404   return NULL;
    405 }
    406 
    407 void JdwpState::Run() {
    408   Runtime* runtime = Runtime::Current();
    409   CHECK(runtime->AttachCurrentThread("JDWP", true, runtime->GetSystemThreadGroup(),
    410                                      !runtime->IsCompiler()));
    411 
    412   VLOG(jdwp) << "JDWP: thread running";
    413 
    414   /*
    415    * Finish initializing, then notify the creating thread that
    416    * we're running.
    417    */
    418   thread_ = Thread::Current();
    419   run = true;
    420 
    421   {
    422     MutexLock locker(thread_, thread_start_lock_);
    423     debug_thread_started_ = true;
    424     thread_start_cond_.Broadcast(thread_);
    425   }
    426 
    427   /* set the thread state to kWaitingInMainDebuggerLoop so GCs don't wait for us */
    428   CHECK_EQ(thread_->GetState(), kNative);
    429   Locks::mutator_lock_->AssertNotHeld(thread_);
    430   thread_->SetState(kWaitingInMainDebuggerLoop);
    431 
    432   /*
    433    * Loop forever if we're in server mode, processing connections.  In
    434    * non-server mode, we bail out of the thread when the debugger drops
    435    * us.
    436    *
    437    * We broadcast a notification when a debugger attaches, after we
    438    * successfully process the handshake.
    439    */
    440   while (run) {
    441     if (options_->server) {
    442       /*
    443        * Block forever, waiting for a connection.  To support the
    444        * "timeout=xxx" option we'll need to tweak this.
    445        */
    446       if (!netState->Accept()) {
    447         break;
    448       }
    449     } else {
    450       /*
    451        * If we're not acting as a server, we need to connect out to the
    452        * debugger.  To support the "timeout=xxx" option we need to
    453        * have a timeout if the handshake reply isn't received in a
    454        * reasonable amount of time.
    455        */
    456       if (!netState->Establish(options_)) {
    457         /* wake anybody who was waiting for us to succeed */
    458         MutexLock mu(thread_, attach_lock_);
    459         debug_thread_id_ = static_cast<ObjectId>(-1);
    460         attach_cond_.Broadcast(thread_);
    461         break;
    462       }
    463     }
    464 
    465     /* prep debug code to handle the new connection */
    466     Dbg::Connected();
    467 
    468     /* process requests until the debugger drops */
    469     bool first = true;
    470     while (!Dbg::IsDisposed()) {
    471       // sanity check -- shouldn't happen?
    472       CHECK_EQ(thread_->GetState(), kWaitingInMainDebuggerLoop);
    473 
    474       if (!netState->ProcessIncoming()) {
    475         /* blocking read */
    476         break;
    477       }
    478 
    479       if (should_exit_) {
    480         exit(exit_status_);
    481       }
    482 
    483       if (first && !netState->IsAwaitingHandshake()) {
    484         /* handshake worked, tell the interpreter that we're active */
    485         first = false;
    486 
    487         /* set thread ID; requires object registry to be active */
    488         {
    489           ScopedObjectAccess soa(thread_);
    490           debug_thread_id_ = Dbg::GetThreadSelfId();
    491         }
    492 
    493         /* wake anybody who's waiting for us */
    494         MutexLock mu(thread_, attach_lock_);
    495         attach_cond_.Broadcast(thread_);
    496       }
    497     }
    498 
    499     netState->Close();
    500 
    501     if (ddm_is_active_) {
    502       ddm_is_active_ = false;
    503 
    504       /* broadcast the disconnect; must be in RUNNING state */
    505       thread_->TransitionFromSuspendedToRunnable();
    506       Dbg::DdmDisconnected();
    507       thread_->TransitionFromRunnableToSuspended(kWaitingInMainDebuggerLoop);
    508     }
    509 
    510     {
    511       ScopedObjectAccess soa(thread_);
    512 
    513       // Release session state, e.g. remove breakpoint instructions.
    514       ResetState();
    515     }
    516     // Tell the rest of the runtime that the debugger is no longer around.
    517     Dbg::Disconnected();
    518 
    519     /* if we had threads suspended, resume them now */
    520     Dbg::UndoDebuggerSuspensions();
    521 
    522     /* if we connected out, this was a one-shot deal */
    523     if (!options_->server) {
    524       run = false;
    525     }
    526   }
    527 
    528   /* back to native, for thread shutdown */
    529   CHECK_EQ(thread_->GetState(), kWaitingInMainDebuggerLoop);
    530   thread_->SetState(kNative);
    531 
    532   VLOG(jdwp) << "JDWP: thread detaching and exiting...";
    533   runtime->DetachCurrentThread();
    534 }
    535 
    536 void JdwpState::NotifyDdmsActive() {
    537   if (!ddm_is_active_) {
    538     ddm_is_active_ = true;
    539     Dbg::DdmConnected();
    540   }
    541 }
    542 
    543 Thread* JdwpState::GetDebugThread() {
    544   return thread_;
    545 }
    546 
    547 /*
    548  * Support routines for waitForDebugger().
    549  *
    550  * We can't have a trivial "waitForDebugger" function that returns the
    551  * instant the debugger connects, because we run the risk of executing code
    552  * before the debugger has had a chance to configure breakpoints or issue
    553  * suspend calls.  It would be nice to just sit in the suspended state, but
    554  * most debuggers don't expect any threads to be suspended when they attach.
    555  *
    556  * There's no JDWP event we can post to tell the debugger, "we've stopped,
    557  * and we like it that way".  We could send a fake breakpoint, which should
    558  * cause the debugger to immediately send a resume, but the debugger might
    559  * send the resume immediately or might throw an exception of its own upon
    560  * receiving a breakpoint event that it didn't ask for.
    561  *
    562  * What we really want is a "wait until the debugger is done configuring
    563  * stuff" event.  We can approximate this with a "wait until the debugger
    564  * has been idle for a brief period".
    565  */
    566 
    567 /*
    568  * Return the time, in milliseconds, since the last debugger activity.
    569  *
    570  * Returns -1 if no debugger is attached, or 0 if we're in the middle of
    571  * processing a debugger request.
    572  */
    573 int64_t JdwpState::LastDebuggerActivity() {
    574   if (!Dbg::IsDebuggerActive()) {
    575     LOG(WARNING) << "no active debugger";
    576     return -1;
    577   }
    578 
    579   int64_t last = last_activity_time_ms_.LoadSequentiallyConsistent();
    580 
    581   /* initializing or in the middle of something? */
    582   if (last == 0) {
    583     VLOG(jdwp) << "+++ last=busy";
    584     return 0;
    585   }
    586 
    587   /* now get the current time */
    588   int64_t now = MilliTime();
    589   CHECK_GE(now, last);
    590 
    591   VLOG(jdwp) << "+++ debugger interval=" << (now - last);
    592   return now - last;
    593 }
    594 
    595 void JdwpState::ExitAfterReplying(int exit_status) {
    596   LOG(WARNING) << "Debugger told VM to exit with status " << exit_status;
    597   should_exit_ = true;
    598   exit_status_ = exit_status;
    599 }
    600 
    601 std::ostream& operator<<(std::ostream& os, const JdwpLocation& rhs) {
    602   os << "JdwpLocation["
    603      << Dbg::GetClassName(rhs.class_id) << "." << Dbg::GetMethodName(rhs.method_id)
    604      << "@" << StringPrintf("%#" PRIx64, rhs.dex_pc) << " " << rhs.type_tag << "]";
    605   return os;
    606 }
    607 
    608 bool operator==(const JdwpLocation& lhs, const JdwpLocation& rhs) {
    609   return lhs.dex_pc == rhs.dex_pc && lhs.method_id == rhs.method_id &&
    610       lhs.class_id == rhs.class_id && lhs.type_tag == rhs.type_tag;
    611 }
    612 
    613 bool operator!=(const JdwpLocation& lhs, const JdwpLocation& rhs) {
    614   return !(lhs == rhs);
    615 }
    616 
    617 }  // namespace JDWP
    618 
    619 }  // namespace art
    620