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