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