Home | History | Annotate | Download | only in adb
      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