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 static void jdwp_process_event(int socket, unsigned events, void* _proc);
    128 static void jdwp_process_list_updated(void);
    129 
    130 struct JdwpProcess;
    131 static std::list<std::unique_ptr<JdwpProcess>> _jdwp_list;
    132 
    133 struct JdwpProcess {
    134     explicit JdwpProcess(int socket) {
    135         this->socket = socket;
    136         this->fde = fdevent_create(socket, jdwp_process_event, this);
    137 
    138         if (!this->fde) {
    139             fatal("could not create fdevent for new JDWP process");
    140         }
    141 
    142         this->fde->state |= FDE_DONT_CLOSE;
    143 
    144         /* start by waiting for the PID */
    145         fdevent_add(this->fde, FDE_READ);
    146     }
    147 
    148     ~JdwpProcess() {
    149         if (this->socket >= 0) {
    150             adb_shutdown(this->socket);
    151             adb_close(this->socket);
    152             this->socket = -1;
    153         }
    154 
    155         if (this->fde) {
    156             fdevent_destroy(this->fde);
    157             this->fde = nullptr;
    158         }
    159 
    160         out_fds.clear();
    161     }
    162 
    163     void RemoveFromList() {
    164         if (this->pid >= 0) {
    165             D("removing pid %d from jdwp process list", this->pid);
    166         } else {
    167             D("removing transient JdwpProcess from list");
    168         }
    169 
    170         auto pred = [this](const auto& proc) { return proc.get() == this; };
    171         _jdwp_list.remove_if(pred);
    172     }
    173 
    174     int32_t pid = -1;
    175     int socket = -1;
    176     fdevent* fde = nullptr;
    177 
    178     std::vector<unique_fd> out_fds;
    179 };
    180 
    181 static size_t jdwp_process_list(char* buffer, size_t bufferlen) {
    182     std::string temp;
    183 
    184     for (auto& proc : _jdwp_list) {
    185         /* skip transient connections */
    186         if (proc->pid < 0) {
    187             continue;
    188         }
    189 
    190         std::string next = std::to_string(proc->pid) + "\n";
    191         if (temp.length() + next.length() > bufferlen) {
    192             D("truncating JDWP process list (max len = %zu)", bufferlen);
    193             break;
    194         }
    195         temp.append(next);
    196     }
    197 
    198     memcpy(buffer, temp.data(), temp.length());
    199     return temp.length();
    200 }
    201 
    202 static size_t jdwp_process_list_msg(char* buffer, size_t bufferlen) {
    203     // Message is length-prefixed with 4 hex digits in ASCII.
    204     static constexpr size_t header_len = 4;
    205     if (bufferlen < header_len) {
    206         fatal("invalid JDWP process list buffer size: %zu", bufferlen);
    207     }
    208 
    209     char head[header_len + 1];
    210     size_t len = jdwp_process_list(buffer + header_len, bufferlen - header_len);
    211     snprintf(head, sizeof head, "%04zx", len);
    212     memcpy(buffer, head, header_len);
    213     return len + header_len;
    214 }
    215 
    216 static void jdwp_process_event(int socket, unsigned events, void* _proc) {
    217     JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(_proc);
    218 
    219     if (events & FDE_READ) {
    220         if (proc->pid < 0) {
    221             ssize_t rc = TEMP_FAILURE_RETRY(recv(socket, &proc->pid, sizeof(proc->pid), 0));
    222             if (rc != sizeof(proc->pid)) {
    223                 D("failed to read jdwp pid: rc = %zd, errno = %s", rc, strerror(errno));
    224                 goto CloseProcess;
    225             }
    226 
    227             /* all is well, keep reading to detect connection closure */
    228             D("Adding pid %d to jdwp process list", proc->pid);
    229             jdwp_process_list_updated();
    230         } else {
    231             /* the pid was read, if we get there it's probably because the connection
    232              * was closed (e.g. the JDWP process exited or crashed) */
    233             char buf[32];
    234 
    235             while (true) {
    236                 int len = TEMP_FAILURE_RETRY(recv(socket, buf, sizeof(buf), 0));
    237 
    238                 if (len == 0) {
    239                     D("terminating JDWP %d connection: EOF", proc->pid);
    240                     break;
    241                 } else if (len < 0) {
    242                     if (len < 0 && errno == EAGAIN) {
    243                         return;
    244                     }
    245 
    246                     D("terminating JDWP %d connection: EOF", proc->pid);
    247                     break;
    248                 } else {
    249                     D("ignoring unexpected JDWP %d control socket activity (%d bytes)", proc->pid,
    250                       len);
    251                 }
    252             }
    253 
    254             goto CloseProcess;
    255         }
    256     }
    257 
    258     if (events & FDE_WRITE) {
    259         D("trying to send fd to JDWP process (count = %zu)", proc->out_fds.size());
    260         if (!proc->out_fds.empty()) {
    261             int fd = proc->out_fds.back().get();
    262             struct cmsghdr* cmsg;
    263             struct msghdr msg;
    264             struct iovec iov;
    265             char dummy = '!';
    266             char buffer[sizeof(struct cmsghdr) + sizeof(int)];
    267 
    268             iov.iov_base = &dummy;
    269             iov.iov_len = 1;
    270             msg.msg_name = NULL;
    271             msg.msg_namelen = 0;
    272             msg.msg_iov = &iov;
    273             msg.msg_iovlen = 1;
    274             msg.msg_flags = 0;
    275             msg.msg_control = buffer;
    276             msg.msg_controllen = sizeof(buffer);
    277 
    278             cmsg = CMSG_FIRSTHDR(&msg);
    279             cmsg->cmsg_len = msg.msg_controllen;
    280             cmsg->cmsg_level = SOL_SOCKET;
    281             cmsg->cmsg_type = SCM_RIGHTS;
    282             ((int*)CMSG_DATA(cmsg))[0] = fd;
    283 
    284             if (!set_file_block_mode(proc->socket, true)) {
    285                 VLOG(JDWP) << "failed to set blocking mode for fd " << proc->socket;
    286                 goto CloseProcess;
    287             }
    288 
    289             int ret = TEMP_FAILURE_RETRY(sendmsg(proc->socket, &msg, 0));
    290             if (ret < 0) {
    291                 D("sending new file descriptor to JDWP %d failed: %s", proc->pid, strerror(errno));
    292                 goto CloseProcess;
    293             }
    294 
    295             D("sent file descriptor %d to JDWP process %d", fd, proc->pid);
    296 
    297             proc->out_fds.pop_back();
    298 
    299             if (!set_file_block_mode(proc->socket, false)) {
    300                 VLOG(JDWP) << "failed to set non-blocking mode for fd " << proc->socket;
    301                 goto CloseProcess;
    302             }
    303 
    304             if (proc->out_fds.empty()) {
    305                 fdevent_del(proc->fde, FDE_WRITE);
    306             }
    307         }
    308     }
    309 
    310     return;
    311 
    312 CloseProcess:
    313     proc->RemoveFromList();
    314     jdwp_process_list_updated();
    315 }
    316 
    317 int create_jdwp_connection_fd(int pid) {
    318     D("looking for pid %d in JDWP process list", pid);
    319 
    320     for (auto& proc : _jdwp_list) {
    321         if (proc->pid == pid) {
    322             int fds[2];
    323 
    324             if (adb_socketpair(fds) < 0) {
    325                 D("%s: socket pair creation failed: %s", __FUNCTION__, strerror(errno));
    326                 return -1;
    327             }
    328             D("socketpair: (%d,%d)", fds[0], fds[1]);
    329 
    330             proc->out_fds.emplace_back(fds[1]);
    331             if (proc->out_fds.size() == 1) {
    332                 fdevent_add(proc->fde, FDE_WRITE);
    333             }
    334 
    335             return fds[0];
    336         }
    337     }
    338     D("search failed !!");
    339     return -1;
    340 }
    341 
    342 /**  VM DEBUG CONTROL SOCKET
    343  **
    344  **  we do implement a custom asocket to receive the data
    345  **/
    346 
    347 /* name of the debug control Unix socket */
    348 #define JDWP_CONTROL_NAME "\0jdwp-control"
    349 #define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME) - 1)
    350 
    351 struct JdwpControl {
    352     int listen_socket;
    353     fdevent* fde;
    354 };
    355 
    356 static JdwpControl _jdwp_control;
    357 
    358 static void jdwp_control_event(int s, unsigned events, void* user);
    359 
    360 static int jdwp_control_init(JdwpControl* control, const char* sockname, int socknamelen) {
    361     sockaddr_un addr;
    362     socklen_t addrlen;
    363     int s;
    364     int maxpath = sizeof(addr.sun_path);
    365     int pathlen = socknamelen;
    366 
    367     if (pathlen >= maxpath) {
    368         D("vm debug control socket name too long (%d extra chars)", pathlen + 1 - maxpath);
    369         return -1;
    370     }
    371 
    372     memset(&addr, 0, sizeof(addr));
    373     addr.sun_family = AF_UNIX;
    374     memcpy(addr.sun_path, sockname, socknamelen);
    375 
    376     s = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
    377     if (s < 0) {
    378         D("could not create vm debug control socket. %d: %s", errno, strerror(errno));
    379         return -1;
    380     }
    381 
    382     addrlen = pathlen + sizeof(addr.sun_family);
    383 
    384     if (bind(s, reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) {
    385         D("could not bind vm debug control socket: %d: %s", errno, strerror(errno));
    386         adb_close(s);
    387         return -1;
    388     }
    389 
    390     if (listen(s, 4) < 0) {
    391         D("listen failed in jdwp control socket: %d: %s", errno, strerror(errno));
    392         adb_close(s);
    393         return -1;
    394     }
    395 
    396     control->listen_socket = s;
    397 
    398     control->fde = fdevent_create(s, jdwp_control_event, control);
    399     if (control->fde == NULL) {
    400         D("could not create fdevent for jdwp control socket");
    401         adb_close(s);
    402         return -1;
    403     }
    404 
    405     /* only wait for incoming connections */
    406     fdevent_add(control->fde, FDE_READ);
    407 
    408     D("jdwp control socket started (%d)", control->listen_socket);
    409     return 0;
    410 }
    411 
    412 static void jdwp_control_event(int s, unsigned events, void* _control) {
    413     JdwpControl* control = (JdwpControl*)_control;
    414 
    415     if (events & FDE_READ) {
    416         int s = adb_socket_accept(control->listen_socket, nullptr, nullptr);
    417         if (s < 0) {
    418             if (errno == ECONNABORTED) {
    419                 /* oops, the JDWP process died really quick */
    420                 D("oops, the JDWP process died really quick");
    421                 return;
    422             } else {
    423                 /* the socket is probably closed ? */
    424                 D("weird accept() failed on jdwp control socket: %s", strerror(errno));
    425                 return;
    426             }
    427         }
    428 
    429         auto proc = std::make_unique<JdwpProcess>(s);
    430         if (!proc) {
    431             fatal("failed to allocate JdwpProcess");
    432         }
    433 
    434         _jdwp_list.emplace_back(std::move(proc));
    435     }
    436 }
    437 
    438 /** "jdwp" local service implementation
    439  ** this simply returns the list of known JDWP process pids
    440  **/
    441 
    442 struct JdwpSocket : public asocket {
    443     bool pass = false;
    444 };
    445 
    446 static void jdwp_socket_close(asocket* s) {
    447     D("LS(%d): closing jdwp socket", s->id);
    448 
    449     if (s->peer) {
    450         D("LS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
    451         s->peer->peer = nullptr;
    452         s->peer->close(s->peer);
    453         s->peer = nullptr;
    454     }
    455 
    456     remove_socket(s);
    457     delete s;
    458 }
    459 
    460 static int jdwp_socket_enqueue(asocket* s, std::string) {
    461     /* you can't write to this asocket */
    462     D("LS(%d): JDWP socket received data?", s->id);
    463     s->peer->close(s->peer);
    464     return -1;
    465 }
    466 
    467 static void jdwp_socket_ready(asocket* s) {
    468     JdwpSocket* jdwp = (JdwpSocket*)s;
    469     asocket* peer = jdwp->peer;
    470 
    471     /* on the first call, send the list of pids,
    472      * on the second one, close the connection
    473      */
    474     if (!jdwp->pass) {
    475         std::string data;
    476         data.resize(s->get_max_payload());
    477         size_t len = jdwp_process_list(&data[0], data.size());
    478         data.resize(len);
    479         peer->enqueue(peer, std::move(data));
    480         jdwp->pass = true;
    481     } else {
    482         peer->close(peer);
    483     }
    484 }
    485 
    486 asocket* create_jdwp_service_socket(void) {
    487     JdwpSocket* s = new JdwpSocket();
    488 
    489     if (!s) {
    490         fatal("failed to allocate JdwpSocket");
    491     }
    492 
    493     install_local_socket(s);
    494 
    495     s->ready = jdwp_socket_ready;
    496     s->enqueue = jdwp_socket_enqueue;
    497     s->close = jdwp_socket_close;
    498     s->pass = false;
    499 
    500     return s;
    501 }
    502 
    503 /** "track-jdwp" local service implementation
    504  ** this periodically sends the list of known JDWP process pids
    505  ** to the client...
    506  **/
    507 
    508 struct JdwpTracker : public asocket {
    509     bool need_initial;
    510 };
    511 
    512 static std::vector<std::unique_ptr<JdwpTracker>> _jdwp_trackers;
    513 
    514 static void jdwp_process_list_updated(void) {
    515     std::string data;
    516     data.resize(1024);
    517     data.resize(jdwp_process_list_msg(&data[0], data.size()));
    518 
    519     for (auto& t : _jdwp_trackers) {
    520         if (t->peer) {
    521             // The tracker might not have been connected yet.
    522             t->peer->enqueue(t->peer, data);
    523         }
    524     }
    525 }
    526 
    527 static void jdwp_tracker_close(asocket* s) {
    528     D("LS(%d): destroying jdwp tracker service", s->id);
    529 
    530     if (s->peer) {
    531         D("LS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
    532         s->peer->peer = nullptr;
    533         s->peer->close(s->peer);
    534         s->peer = nullptr;
    535     }
    536 
    537     remove_socket(s);
    538 
    539     auto pred = [s](const auto& tracker) { return tracker.get() == s; };
    540     _jdwp_trackers.erase(std::remove_if(_jdwp_trackers.begin(), _jdwp_trackers.end(), pred),
    541                          _jdwp_trackers.end());
    542 }
    543 
    544 static void jdwp_tracker_ready(asocket* s) {
    545     JdwpTracker* t = (JdwpTracker*)s;
    546 
    547     if (t->need_initial) {
    548         std::string data;
    549         data.resize(s->get_max_payload());
    550         data.resize(jdwp_process_list_msg(&data[0], data.size()));
    551         t->need_initial = false;
    552         s->peer->enqueue(s->peer, std::move(data));
    553     }
    554 }
    555 
    556 static int jdwp_tracker_enqueue(asocket* s, std::string) {
    557     /* you can't write to this socket */
    558     D("LS(%d): JDWP tracker received data?", s->id);
    559     s->peer->close(s->peer);
    560     return -1;
    561 }
    562 
    563 asocket* create_jdwp_tracker_service_socket(void) {
    564     auto t = std::make_unique<JdwpTracker>();
    565     if (!t) {
    566         fatal("failed to allocate JdwpTracker");
    567     }
    568 
    569     memset(t.get(), 0, sizeof(asocket));
    570 
    571     install_local_socket(t.get());
    572     D("LS(%d): created new jdwp tracker service", t->id);
    573 
    574     t->ready = jdwp_tracker_ready;
    575     t->enqueue = jdwp_tracker_enqueue;
    576     t->close = jdwp_tracker_close;
    577     t->need_initial = true;
    578 
    579     asocket* result = t.get();
    580 
    581     _jdwp_trackers.emplace_back(std::move(t));
    582 
    583     return result;
    584 }
    585 
    586 int init_jdwp(void) {
    587     return jdwp_control_init(&_jdwp_control, JDWP_CONTROL_NAME, JDWP_CONTROL_NAME_LEN);
    588 }
    589 
    590 #endif /* !ADB_HOST */
    591