jdwp_main.cc revision 37f3c968ecd04e77802fe17bb82dabc07de21ca1
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 29namespace art { 30 31namespace JDWP { 32 33static void* StartJdwpThread(void* arg); 34 35/* 36 * JdwpNetStateBase class implementation 37 */ 38JdwpNetStateBase::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 47JdwpNetStateBase::~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 58bool JdwpNetStateBase::MakePipe() { 59 if (pipe(wake_pipe_) == -1) { 60 PLOG(ERROR) << "pipe failed"; 61 return false; 62 } 63 return true; 64} 65 66void 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 74void 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 87bool 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 98bool JdwpNetStateBase::IsAwaitingHandshake() { 99 return awaiting_handshake_; 100} 101 102void JdwpNetStateBase::SetAwaitingHandshake(bool new_state) { 103 awaiting_handshake_ = new_state; 104} 105 106bool 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. 113void 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 */ 127ssize_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 */ 136ssize_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 141bool JdwpState::IsConnected() { 142 return netState != NULL && netState->IsConnected(); 143} 144 145void JdwpState::SendBufferedRequest(uint32_t type, const std::vector<iovec>& iov) { 146 if (netState->clientSock < 0) { 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 169void JdwpState::SendRequest(ExpandBuf* pReq) { 170 if (netState->clientSock < 0) { 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 */ 188uint32_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 */ 196uint32_t JdwpState::NextEventSerial() { 197 return event_serial_++; 198} 199 200JdwpState::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 */ 235JdwpState* 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 state->attach_cond_.Wait(self); 287 } 288 if (!state->IsActive()) { 289 LOG(ERROR) << "JDWP connection failed"; 290 return NULL; 291 } 292 293 LOG(INFO) << "JDWP connected"; 294 295 /* 296 * Ordinarily we would pause briefly to allow the debugger to set 297 * breakpoints and so on, but for "suspend=y" the VM init code will 298 * pause the VM when it sends the VM_START message. 299 */ 300 } 301 302 return state.release(); 303} 304 305/* 306 * Reset all session-related state. There should not be an active connection 307 * to the client at this point. The rest of the VM still thinks there is 308 * a debugger attached. 309 * 310 * This includes freeing up the debugger event list. 311 */ 312void JdwpState::ResetState() { 313 /* could reset the serial numbers, but no need to */ 314 315 UnregisterAll(); 316 { 317 MutexLock mu(Thread::Current(), event_list_lock_); 318 CHECK(event_list_ == NULL); 319 } 320 321 Dbg::ProcessDelayedFullUndeoptimizations(); 322 323 /* 324 * Should not have one of these in progress. If the debugger went away 325 * mid-request, though, we could see this. 326 */ 327 if (event_thread_id_ != 0) { 328 LOG(WARNING) << "Resetting state while event in progress"; 329 DCHECK(false); 330 } 331} 332 333/* 334 * Tell the JDWP thread to shut down. Frees "state". 335 */ 336JdwpState::~JdwpState() { 337 if (netState != NULL) { 338 if (IsConnected()) { 339 PostVMDeath(); 340 } 341 342 /* 343 * Close down the network to inspire the thread to halt. 344 */ 345 VLOG(jdwp) << "JDWP shutting down net..."; 346 netState->Shutdown(); 347 348 if (debug_thread_started_) { 349 run = false; 350 void* threadReturn; 351 if (pthread_join(pthread_, &threadReturn) != 0) { 352 LOG(WARNING) << "JDWP thread join failed"; 353 } 354 } 355 356 VLOG(jdwp) << "JDWP freeing netstate..."; 357 delete netState; 358 netState = NULL; 359 } 360 CHECK(netState == NULL); 361 362 ResetState(); 363} 364 365/* 366 * Are we talking to a debugger? 367 */ 368bool JdwpState::IsActive() { 369 return IsConnected(); 370} 371 372// Returns "false" if we encounter a connection-fatal error. 373bool JdwpState::HandlePacket() { 374 JdwpNetStateBase* netStateBase = reinterpret_cast<JdwpNetStateBase*>(netState); 375 JDWP::Request request(netStateBase->input_buffer_, netStateBase->input_count_); 376 377 ExpandBuf* pReply = expandBufAlloc(); 378 size_t replyLength = ProcessRequest(request, pReply); 379 ssize_t cc = netStateBase->WritePacket(pReply, replyLength); 380 381 /* 382 * We processed this request and sent its reply. Notify other threads waiting for us they can now 383 * send events. 384 */ 385 EndProcessingRequest(); 386 387 if (cc != static_cast<ssize_t>(replyLength)) { 388 PLOG(ERROR) << "Failed sending reply to debugger"; 389 expandBufFree(pReply); 390 return false; 391 } 392 expandBufFree(pReply); 393 netStateBase->ConsumeBytes(request.GetLength()); 394 return true; 395} 396 397/* 398 * Entry point for JDWP thread. The thread was created through the VM 399 * mechanisms, so there is a java/lang/Thread associated with us. 400 */ 401static void* StartJdwpThread(void* arg) { 402 JdwpState* state = reinterpret_cast<JdwpState*>(arg); 403 CHECK(state != NULL); 404 405 state->Run(); 406 return NULL; 407} 408 409void JdwpState::Run() { 410 Runtime* runtime = Runtime::Current(); 411 CHECK(runtime->AttachCurrentThread("JDWP", true, runtime->GetSystemThreadGroup(), 412 !runtime->IsCompiler())); 413 414 VLOG(jdwp) << "JDWP: thread running"; 415 416 /* 417 * Finish initializing, then notify the creating thread that 418 * we're running. 419 */ 420 thread_ = Thread::Current(); 421 run = true; 422 423 { 424 MutexLock locker(thread_, thread_start_lock_); 425 debug_thread_started_ = true; 426 thread_start_cond_.Broadcast(thread_); 427 } 428 429 /* set the thread state to kWaitingInMainDebuggerLoop so GCs don't wait for us */ 430 CHECK_EQ(thread_->GetState(), kNative); 431 Locks::mutator_lock_->AssertNotHeld(thread_); 432 thread_->SetState(kWaitingInMainDebuggerLoop); 433 434 /* 435 * Loop forever if we're in server mode, processing connections. In 436 * non-server mode, we bail out of the thread when the debugger drops 437 * us. 438 * 439 * We broadcast a notification when a debugger attaches, after we 440 * successfully process the handshake. 441 */ 442 while (run) { 443 if (options_->server) { 444 /* 445 * Block forever, waiting for a connection. To support the 446 * "timeout=xxx" option we'll need to tweak this. 447 */ 448 if (!netState->Accept()) { 449 break; 450 } 451 } else { 452 /* 453 * If we're not acting as a server, we need to connect out to the 454 * debugger. To support the "timeout=xxx" option we need to 455 * have a timeout if the handshake reply isn't received in a 456 * reasonable amount of time. 457 */ 458 if (!netState->Establish(options_)) { 459 /* wake anybody who was waiting for us to succeed */ 460 MutexLock mu(thread_, attach_lock_); 461 attach_cond_.Broadcast(thread_); 462 break; 463 } 464 } 465 466 /* prep debug code to handle the new connection */ 467 Dbg::Connected(); 468 469 /* process requests until the debugger drops */ 470 bool first = true; 471 while (!Dbg::IsDisposed()) { 472 // sanity check -- shouldn't happen? 473 CHECK_EQ(thread_->GetState(), kWaitingInMainDebuggerLoop); 474 475 if (!netState->ProcessIncoming()) { 476 /* blocking read */ 477 break; 478 } 479 480 if (should_exit_) { 481 exit(exit_status_); 482 } 483 484 if (first && !netState->IsAwaitingHandshake()) { 485 /* handshake worked, tell the interpreter that we're active */ 486 first = false; 487 488 /* set thread ID; requires object registry to be active */ 489 { 490 ScopedObjectAccess soa(thread_); 491 debug_thread_id_ = Dbg::GetThreadSelfId(); 492 } 493 494 /* wake anybody who's waiting for us */ 495 MutexLock mu(thread_, attach_lock_); 496 attach_cond_.Broadcast(thread_); 497 } 498 } 499 500 netState->Close(); 501 502 if (ddm_is_active_) { 503 ddm_is_active_ = false; 504 505 /* broadcast the disconnect; must be in RUNNING state */ 506 thread_->TransitionFromSuspendedToRunnable(); 507 Dbg::DdmDisconnected(); 508 thread_->TransitionFromRunnableToSuspended(kWaitingInMainDebuggerLoop); 509 } 510 511 { 512 ScopedObjectAccess soa(thread_); 513 514 // Release session state, e.g. remove breakpoint instructions. 515 ResetState(); 516 } 517 // Tell the rest of the runtime that the debugger is no longer around. 518 Dbg::Disconnected(); 519 520 /* if we had threads suspended, resume them now */ 521 Dbg::UndoDebuggerSuspensions(); 522 523 /* if we connected out, this was a one-shot deal */ 524 if (!options_->server) { 525 run = false; 526 } 527 } 528 529 /* back to native, for thread shutdown */ 530 CHECK_EQ(thread_->GetState(), kWaitingInMainDebuggerLoop); 531 thread_->SetState(kNative); 532 533 VLOG(jdwp) << "JDWP: thread detaching and exiting..."; 534 runtime->DetachCurrentThread(); 535} 536 537void JdwpState::NotifyDdmsActive() { 538 if (!ddm_is_active_) { 539 ddm_is_active_ = true; 540 Dbg::DdmConnected(); 541 } 542} 543 544Thread* JdwpState::GetDebugThread() { 545 return thread_; 546} 547 548/* 549 * Support routines for waitForDebugger(). 550 * 551 * We can't have a trivial "waitForDebugger" function that returns the 552 * instant the debugger connects, because we run the risk of executing code 553 * before the debugger has had a chance to configure breakpoints or issue 554 * suspend calls. It would be nice to just sit in the suspended state, but 555 * most debuggers don't expect any threads to be suspended when they attach. 556 * 557 * There's no JDWP event we can post to tell the debugger, "we've stopped, 558 * and we like it that way". We could send a fake breakpoint, which should 559 * cause the debugger to immediately send a resume, but the debugger might 560 * send the resume immediately or might throw an exception of its own upon 561 * receiving a breakpoint event that it didn't ask for. 562 * 563 * What we really want is a "wait until the debugger is done configuring 564 * stuff" event. We can approximate this with a "wait until the debugger 565 * has been idle for a brief period". 566 */ 567 568/* 569 * Return the time, in milliseconds, since the last debugger activity. 570 * 571 * Returns -1 if no debugger is attached, or 0 if we're in the middle of 572 * processing a debugger request. 573 */ 574int64_t JdwpState::LastDebuggerActivity() { 575 if (!Dbg::IsDebuggerActive()) { 576 LOG(WARNING) << "no active debugger"; 577 return -1; 578 } 579 580 int64_t last = last_activity_time_ms_.LoadSequentiallyConsistent(); 581 582 /* initializing or in the middle of something? */ 583 if (last == 0) { 584 VLOG(jdwp) << "+++ last=busy"; 585 return 0; 586 } 587 588 /* now get the current time */ 589 int64_t now = MilliTime(); 590 CHECK_GE(now, last); 591 592 VLOG(jdwp) << "+++ debugger interval=" << (now - last); 593 return now - last; 594} 595 596void JdwpState::ExitAfterReplying(int exit_status) { 597 LOG(WARNING) << "Debugger told VM to exit with status " << exit_status; 598 should_exit_ = true; 599 exit_status_ = exit_status; 600} 601 602std::ostream& operator<<(std::ostream& os, const JdwpLocation& rhs) { 603 os << "JdwpLocation[" 604 << Dbg::GetClassName(rhs.class_id) << "." << Dbg::GetMethodName(rhs.method_id) 605 << "@" << StringPrintf("%#" PRIx64, rhs.dex_pc) << " " << rhs.type_tag << "]"; 606 return os; 607} 608 609bool operator==(const JdwpLocation& lhs, const JdwpLocation& rhs) { 610 return lhs.dex_pc == rhs.dex_pc && lhs.method_id == rhs.method_id && 611 lhs.class_id == rhs.class_id && lhs.type_tag == rhs.type_tag; 612} 613 614bool operator!=(const JdwpLocation& lhs, const JdwpLocation& rhs) { 615 return !(lhs == rhs); 616} 617 618} // namespace JDWP 619 620} // namespace art 621