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