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