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