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