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