1 /* implement the "debug-ports" and "track-debug-ports" device services */ 2 #include "sysdeps.h" 3 #define TRACE_TAG TRACE_JDWP 4 #include "adb.h" 5 #include <errno.h> 6 #include <stdio.h> 7 #include <string.h> 8 #include <unistd.h> 9 10 /* here's how these things work. 11 12 when adbd starts, it creates a unix server socket 13 named @vm-debug-control (@ is a shortcut for "first byte is zero" 14 to use the private namespace instead of the file system) 15 16 when a new JDWP daemon thread starts in a new VM process, it creates 17 a connection to @vm-debug-control to announce its availability. 18 19 20 JDWP thread @vm-debug-control 21 | | 22 |-------------------------------> | 23 | hello I'm in process <pid> | 24 | | 25 | | 26 27 the connection is kept alive. it will be closed automatically if 28 the JDWP process terminates (this allows adbd to detect dead 29 processes). 30 31 adbd thus maintains a list of "active" JDWP processes. it can send 32 its content to clients through the "device:debug-ports" service, 33 or even updates through the "device:track-debug-ports" service. 34 35 when a debugger wants to connect, it simply runs the command 36 equivalent to "adb forward tcp:<hostport> jdwp:<pid>" 37 38 "jdwp:<pid>" is a new forward destination format used to target 39 a given JDWP process on the device. when sutch a request arrives, 40 adbd does the following: 41 42 - first, it calls socketpair() to create a pair of equivalent 43 sockets. 44 45 - it attaches the first socket in the pair to a local socket 46 which is itself attached to the transport's remote socket: 47 48 49 - it sends the file descriptor of the second socket directly 50 to the JDWP process with the help of sendmsg() 51 52 53 JDWP thread @vm-debug-control 54 | | 55 | <----------------------| 56 | OK, try this file descriptor | 57 | | 58 | | 59 60 then, the JDWP thread uses this new socket descriptor as its 61 pass-through connection to the debugger (and receives the 62 JDWP-Handshake message, answers to it, etc...) 63 64 this gives the following graphics: 65 ____________________________________ 66 | | 67 | ADB Server (host) | 68 | | 69 Debugger <---> LocalSocket <----> RemoteSocket | 70 | ^^ | 71 |___________________________||_______| 72 || 73 Transport || 74 (TCP for emulator - USB for device) || 75 || 76 ___________________________||_______ 77 | || | 78 | ADBD (device) || | 79 | VV | 80 JDWP <======> LocalSocket <----> RemoteSocket | 81 | | 82 |____________________________________| 83 84 due to the way adb works, this doesn't need a special socket 85 type or fancy handling of socket termination if either the debugger 86 or the JDWP process closes the connection. 87 88 THIS IS THE SIMPLEST IMPLEMENTATION I COULD FIND, IF YOU HAPPEN 89 TO HAVE A BETTER IDEA, LET ME KNOW - Digit 90 91 **********************************************************************/ 92 93 /** JDWP PID List Support Code 94 ** for each JDWP process, we record its pid and its connected socket 95 **/ 96 97 #define MAX_OUT_FDS 4 98 99 #if !ADB_HOST 100 101 #include <sys/socket.h> 102 #include <sys/un.h> 103 104 typedef struct JdwpProcess JdwpProcess; 105 struct JdwpProcess { 106 JdwpProcess* next; 107 JdwpProcess* prev; 108 int pid; 109 int socket; 110 fdevent* fde; 111 112 char in_buff[4]; /* input character to read PID */ 113 int in_len; /* number from JDWP process */ 114 115 int out_fds[MAX_OUT_FDS]; /* output array of file descriptors */ 116 int out_count; /* to send to the JDWP process */ 117 }; 118 119 static JdwpProcess _jdwp_list; 120 121 static int 122 jdwp_process_list( char* buffer, int bufferlen ) 123 { 124 char* end = buffer + bufferlen; 125 char* p = buffer; 126 JdwpProcess* proc = _jdwp_list.next; 127 128 for ( ; proc != &_jdwp_list; proc = proc->next ) { 129 int len; 130 131 /* skip transient connections */ 132 if (proc->pid < 0) 133 continue; 134 135 len = snprintf(p, end-p, "%d\n", proc->pid); 136 if (p + len >= end) 137 break; 138 p += len; 139 } 140 p[0] = 0; 141 return (p - buffer); 142 } 143 144 145 static int 146 jdwp_process_list_msg( char* buffer, int bufferlen ) 147 { 148 char head[5]; 149 int len = jdwp_process_list( buffer+4, bufferlen-4 ); 150 snprintf(head, sizeof head, "%04x", len); 151 memcpy(buffer, head, 4); 152 return len + 4; 153 } 154 155 156 static void jdwp_process_list_updated(void); 157 158 static void 159 jdwp_process_free( JdwpProcess* proc ) 160 { 161 if (proc) { 162 int n; 163 164 proc->prev->next = proc->next; 165 proc->next->prev = proc->prev; 166 167 if (proc->socket >= 0) { 168 adb_shutdown(proc->socket); 169 adb_close(proc->socket); 170 proc->socket = -1; 171 } 172 173 if (proc->fde != NULL) { 174 fdevent_destroy(proc->fde); 175 proc->fde = NULL; 176 } 177 proc->pid = -1; 178 179 for (n = 0; n < proc->out_count; n++) { 180 adb_close(proc->out_fds[n]); 181 } 182 proc->out_count = 0; 183 184 free(proc); 185 186 jdwp_process_list_updated(); 187 } 188 } 189 190 191 static void jdwp_process_event(int, unsigned, void*); /* forward */ 192 193 194 static JdwpProcess* 195 jdwp_process_alloc( int socket ) 196 { 197 JdwpProcess* proc = calloc(1,sizeof(*proc)); 198 199 if (proc == NULL) { 200 D("not enough memory to create new JDWP process\n"); 201 return NULL; 202 } 203 204 proc->socket = socket; 205 proc->pid = -1; 206 proc->next = proc; 207 proc->prev = proc; 208 209 proc->fde = fdevent_create( socket, jdwp_process_event, proc ); 210 if (proc->fde == NULL) { 211 D("could not create fdevent for new JDWP process\n" ); 212 free(proc); 213 return NULL; 214 } 215 216 proc->fde->state |= FDE_DONT_CLOSE; 217 proc->in_len = 0; 218 proc->out_count = 0; 219 220 /* append to list */ 221 proc->next = &_jdwp_list; 222 proc->prev = proc->next->prev; 223 224 proc->prev->next = proc; 225 proc->next->prev = proc; 226 227 /* start by waiting for the PID */ 228 fdevent_add(proc->fde, FDE_READ); 229 230 return proc; 231 } 232 233 234 static void 235 jdwp_process_event( int socket, unsigned events, void* _proc ) 236 { 237 JdwpProcess* proc = _proc; 238 239 if (events & FDE_READ) { 240 if (proc->pid < 0) { 241 /* read the PID as a 4-hexchar string */ 242 char* p = proc->in_buff + proc->in_len; 243 int size = 4 - proc->in_len; 244 char temp[5]; 245 while (size > 0) { 246 int len = recv( socket, p, size, 0 ); 247 if (len < 0) { 248 if (errno == EINTR) 249 continue; 250 if (errno == EAGAIN) 251 return; 252 /* this can fail here if the JDWP process crashes very fast */ 253 D("weird unknown JDWP process failure: %s\n", 254 strerror(errno)); 255 256 goto CloseProcess; 257 } 258 if (len == 0) { /* end of stream ? */ 259 D("weird end-of-stream from unknown JDWP process\n"); 260 goto CloseProcess; 261 } 262 p += len; 263 proc->in_len += len; 264 size -= len; 265 } 266 /* we have read 4 characters, now decode the pid */ 267 memcpy(temp, proc->in_buff, 4); 268 temp[4] = 0; 269 270 if (sscanf( temp, "%04x", &proc->pid ) != 1) { 271 D("could not decode JDWP %p PID number: '%s'\n", proc, temp); 272 goto CloseProcess; 273 } 274 275 /* all is well, keep reading to detect connection closure */ 276 D("Adding pid %d to jdwp process list\n", proc->pid); 277 jdwp_process_list_updated(); 278 } 279 else 280 { 281 /* the pid was read, if we get there it's probably because the connection 282 * was closed (e.g. the JDWP process exited or crashed) */ 283 char buf[32]; 284 285 for (;;) { 286 int len = recv(socket, buf, sizeof(buf), 0); 287 288 if (len <= 0) { 289 if (len < 0 && errno == EINTR) 290 continue; 291 if (len < 0 && errno == EAGAIN) 292 return; 293 else { 294 D("terminating JDWP %d connection: %s\n", proc->pid, 295 strerror(errno)); 296 break; 297 } 298 } 299 else { 300 D( "ignoring unexpected JDWP %d control socket activity (%d bytes)\n", 301 proc->pid, len ); 302 } 303 } 304 305 CloseProcess: 306 if (proc->pid >= 0) 307 D( "remove pid %d to jdwp process list\n", proc->pid ); 308 jdwp_process_free(proc); 309 return; 310 } 311 } 312 313 if (events & FDE_WRITE) { 314 D("trying to write to JDWP pid controli (count=%d first=%d) %d\n", 315 proc->pid, proc->out_count, proc->out_fds[0]); 316 if (proc->out_count > 0) { 317 int fd = proc->out_fds[0]; 318 int n, ret; 319 struct cmsghdr* cmsg; 320 struct msghdr msg; 321 struct iovec iov; 322 char dummy = '!'; 323 char buffer[sizeof(struct cmsghdr) + sizeof(int)]; 324 int flags; 325 326 iov.iov_base = &dummy; 327 iov.iov_len = 1; 328 msg.msg_name = NULL; 329 msg.msg_namelen = 0; 330 msg.msg_iov = &iov; 331 msg.msg_iovlen = 1; 332 msg.msg_flags = 0; 333 msg.msg_control = buffer; 334 msg.msg_controllen = sizeof(buffer); 335 336 cmsg = CMSG_FIRSTHDR(&msg); 337 cmsg->cmsg_len = msg.msg_controllen; 338 cmsg->cmsg_level = SOL_SOCKET; 339 cmsg->cmsg_type = SCM_RIGHTS; 340 ((int*)CMSG_DATA(cmsg))[0] = fd; 341 342 flags = fcntl(proc->socket,F_GETFL,0); 343 344 if (flags == -1) { 345 D("failed to get cntl flags for socket %d: %s\n", 346 proc->pid, strerror(errno)); 347 goto CloseProcess; 348 349 } 350 351 if (fcntl(proc->socket, F_SETFL, flags & ~O_NONBLOCK) == -1) { 352 D("failed to remove O_NONBLOCK flag for socket %d: %s\n", 353 proc->pid, strerror(errno)); 354 goto CloseProcess; 355 } 356 357 for (;;) { 358 ret = sendmsg(proc->socket, &msg, 0); 359 if (ret >= 0) { 360 adb_close(fd); 361 break; 362 } 363 if (errno == EINTR) 364 continue; 365 D("sending new file descriptor to JDWP %d failed: %s\n", 366 proc->pid, strerror(errno)); 367 goto CloseProcess; 368 } 369 370 D("sent file descriptor %d to JDWP process %d\n", 371 fd, proc->pid); 372 373 for (n = 1; n < proc->out_count; n++) 374 proc->out_fds[n-1] = proc->out_fds[n]; 375 376 if (fcntl(proc->socket, F_SETFL, flags) == -1) { 377 D("failed to set O_NONBLOCK flag for socket %d: %s\n", 378 proc->pid, strerror(errno)); 379 goto CloseProcess; 380 } 381 382 if (--proc->out_count == 0) 383 fdevent_del( proc->fde, FDE_WRITE ); 384 } 385 } 386 } 387 388 389 int 390 create_jdwp_connection_fd(int pid) 391 { 392 JdwpProcess* proc = _jdwp_list.next; 393 394 D("looking for pid %d in JDWP process list\n", pid); 395 for ( ; proc != &_jdwp_list; proc = proc->next ) { 396 if (proc->pid == pid) { 397 goto FoundIt; 398 } 399 } 400 D("search failed !!\n"); 401 return -1; 402 403 FoundIt: 404 { 405 int fds[2]; 406 407 if (proc->out_count >= MAX_OUT_FDS) { 408 D("%s: too many pending JDWP connection for pid %d\n", 409 __FUNCTION__, pid); 410 return -1; 411 } 412 413 if (adb_socketpair(fds) < 0) { 414 D("%s: socket pair creation failed: %s\n", 415 __FUNCTION__, strerror(errno)); 416 return -1; 417 } 418 419 proc->out_fds[ proc->out_count ] = fds[1]; 420 if (++proc->out_count == 1) 421 fdevent_add( proc->fde, FDE_WRITE ); 422 423 return fds[0]; 424 } 425 } 426 427 /** VM DEBUG CONTROL SOCKET 428 ** 429 ** we do implement a custom asocket to receive the data 430 **/ 431 432 /* name of the debug control Unix socket */ 433 #define JDWP_CONTROL_NAME "\0jdwp-control" 434 #define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME)-1) 435 436 typedef struct { 437 int listen_socket; 438 fdevent* fde; 439 440 } JdwpControl; 441 442 443 static void 444 jdwp_control_event(int s, unsigned events, void* user); 445 446 447 static int 448 jdwp_control_init( JdwpControl* control, 449 const char* sockname, 450 int socknamelen ) 451 { 452 struct sockaddr_un addr; 453 socklen_t addrlen; 454 int s; 455 int maxpath = sizeof(addr.sun_path); 456 int pathlen = socknamelen; 457 458 if (pathlen >= maxpath) { 459 D( "vm debug control socket name too long (%d extra chars)\n", 460 pathlen+1-maxpath ); 461 return -1; 462 } 463 464 memset(&addr, 0, sizeof(addr)); 465 addr.sun_family = AF_UNIX; 466 memcpy(addr.sun_path, sockname, socknamelen); 467 468 s = socket( AF_UNIX, SOCK_STREAM, 0 ); 469 if (s < 0) { 470 D( "could not create vm debug control socket. %d: %s\n", 471 errno, strerror(errno)); 472 return -1; 473 } 474 475 addrlen = (pathlen + sizeof(addr.sun_family)); 476 477 if (bind(s, (struct sockaddr*)&addr, addrlen) < 0) { 478 D( "could not bind vm debug control socket: %d: %s\n", 479 errno, strerror(errno) ); 480 adb_close(s); 481 return -1; 482 } 483 484 if ( listen(s, 4) < 0 ) { 485 D("listen failed in jdwp control socket: %d: %s\n", 486 errno, strerror(errno)); 487 adb_close(s); 488 return -1; 489 } 490 491 control->listen_socket = s; 492 493 control->fde = fdevent_create(s, jdwp_control_event, control); 494 if (control->fde == NULL) { 495 D( "could not create fdevent for jdwp control socket\n" ); 496 adb_close(s); 497 return -1; 498 } 499 500 /* only wait for incoming connections */ 501 fdevent_add(control->fde, FDE_READ); 502 close_on_exec(s); 503 504 D("jdwp control socket started (%d)\n", control->listen_socket); 505 return 0; 506 } 507 508 509 static void 510 jdwp_control_event( int s, unsigned events, void* _control ) 511 { 512 JdwpControl* control = (JdwpControl*) _control; 513 514 if (events & FDE_READ) { 515 struct sockaddr addr; 516 socklen_t addrlen = sizeof(addr); 517 int s = -1; 518 JdwpProcess* proc; 519 520 do { 521 s = adb_socket_accept( control->listen_socket, &addr, &addrlen ); 522 if (s < 0) { 523 if (errno == EINTR) 524 continue; 525 if (errno == ECONNABORTED) { 526 /* oops, the JDWP process died really quick */ 527 D("oops, the JDWP process died really quick\n"); 528 return; 529 } 530 /* the socket is probably closed ? */ 531 D( "weird accept() failed on jdwp control socket: %s\n", 532 strerror(errno) ); 533 return; 534 } 535 } 536 while (s < 0); 537 538 proc = jdwp_process_alloc( s ); 539 if (proc == NULL) 540 return; 541 } 542 } 543 544 545 static JdwpControl _jdwp_control; 546 547 /** "jdwp" local service implementation 548 ** this simply returns the list of known JDWP process pids 549 **/ 550 551 typedef struct { 552 asocket socket; 553 int pass; 554 } JdwpSocket; 555 556 static void 557 jdwp_socket_close( asocket* s ) 558 { 559 asocket* peer = s->peer; 560 561 remove_socket(s); 562 563 if (peer) { 564 peer->peer = NULL; 565 peer->close(peer); 566 } 567 free(s); 568 } 569 570 static int 571 jdwp_socket_enqueue( asocket* s, apacket* p ) 572 { 573 /* you can't write to this asocket */ 574 put_apacket(p); 575 s->peer->close(s->peer); 576 return -1; 577 } 578 579 580 static void 581 jdwp_socket_ready( asocket* s ) 582 { 583 JdwpSocket* jdwp = (JdwpSocket*)s; 584 asocket* peer = jdwp->socket.peer; 585 586 /* on the first call, send the list of pids, 587 * on the second one, close the connection 588 */ 589 if (jdwp->pass == 0) { 590 apacket* p = get_apacket(); 591 p->len = jdwp_process_list((char*)p->data, MAX_PAYLOAD); 592 peer->enqueue(peer, p); 593 jdwp->pass = 1; 594 } 595 else { 596 peer->close(peer); 597 } 598 } 599 600 asocket* 601 create_jdwp_service_socket( void ) 602 { 603 JdwpSocket* s = calloc(sizeof(*s),1); 604 605 if (s == NULL) 606 return NULL; 607 608 install_local_socket(&s->socket); 609 610 s->socket.ready = jdwp_socket_ready; 611 s->socket.enqueue = jdwp_socket_enqueue; 612 s->socket.close = jdwp_socket_close; 613 s->pass = 0; 614 615 return &s->socket; 616 } 617 618 /** "track-jdwp" local service implementation 619 ** this periodically sends the list of known JDWP process pids 620 ** to the client... 621 **/ 622 623 typedef struct JdwpTracker JdwpTracker; 624 625 struct JdwpTracker { 626 asocket socket; 627 JdwpTracker* next; 628 JdwpTracker* prev; 629 int need_update; 630 }; 631 632 static JdwpTracker _jdwp_trackers_list; 633 634 635 static void 636 jdwp_process_list_updated(void) 637 { 638 char buffer[1024]; 639 int len; 640 JdwpTracker* t = _jdwp_trackers_list.next; 641 642 len = jdwp_process_list_msg(buffer, sizeof(buffer)); 643 644 for ( ; t != &_jdwp_trackers_list; t = t->next ) { 645 apacket* p = get_apacket(); 646 asocket* peer = t->socket.peer; 647 memcpy(p->data, buffer, len); 648 p->len = len; 649 peer->enqueue( peer, p ); 650 } 651 } 652 653 static void 654 jdwp_tracker_close( asocket* s ) 655 { 656 JdwpTracker* tracker = (JdwpTracker*) s; 657 asocket* peer = s->peer; 658 659 if (peer) { 660 peer->peer = NULL; 661 peer->close(peer); 662 } 663 664 remove_socket(s); 665 666 tracker->prev->next = tracker->next; 667 tracker->next->prev = tracker->prev; 668 669 free(s); 670 } 671 672 static void 673 jdwp_tracker_ready( asocket* s ) 674 { 675 JdwpTracker* t = (JdwpTracker*) s; 676 677 if (t->need_update) { 678 apacket* p = get_apacket(); 679 t->need_update = 0; 680 p->len = jdwp_process_list_msg((char*)p->data, sizeof(p->data)); 681 s->peer->enqueue(s->peer, p); 682 } 683 } 684 685 static int 686 jdwp_tracker_enqueue( asocket* s, apacket* p ) 687 { 688 /* you can't write to this socket */ 689 put_apacket(p); 690 s->peer->close(s->peer); 691 return -1; 692 } 693 694 695 asocket* 696 create_jdwp_tracker_service_socket( void ) 697 { 698 JdwpTracker* t = calloc(sizeof(*t),1); 699 700 if (t == NULL) 701 return NULL; 702 703 t->next = &_jdwp_trackers_list; 704 t->prev = t->next->prev; 705 706 t->next->prev = t; 707 t->prev->next = t; 708 709 install_local_socket(&t->socket); 710 711 t->socket.ready = jdwp_tracker_ready; 712 t->socket.enqueue = jdwp_tracker_enqueue; 713 t->socket.close = jdwp_tracker_close; 714 t->need_update = 1; 715 716 return &t->socket; 717 } 718 719 720 int 721 init_jdwp(void) 722 { 723 _jdwp_list.next = &_jdwp_list; 724 _jdwp_list.prev = &_jdwp_list; 725 726 _jdwp_trackers_list.next = &_jdwp_trackers_list; 727 _jdwp_trackers_list.prev = &_jdwp_trackers_list; 728 729 return jdwp_control_init( &_jdwp_control, 730 JDWP_CONTROL_NAME, 731 JDWP_CONTROL_NAME_LEN ); 732 } 733 734 #endif /* !ADB_HOST */ 735 736