Home | History | Annotate | Download | only in jdwp
      1 /*
      2  * Copyright (C) 2008 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 #include "jdwp/JdwpPriv.h"
     18 #include "jdwp/JdwpHandler.h"
     19 #include <sys/socket.h>
     20 #include <sys/un.h>
     21 #include <errno.h>
     22 #include <unistd.h>
     23 #include <cutils/sockets.h>
     24 
     25 /*
     26  * The JDWP <-> ADB transport protocol is explained in detail
     27  * in system/core/adb/jdwp_service.c. Here's a summary.
     28  *
     29  * 1/ when the JDWP thread starts, it tries to connect to a Unix
     30  *    domain stream socket (@jdwp-control) that is opened by the
     31  *    ADB daemon.
     32  *
     33  * 2/ it then sends the current process PID as a string of 4 hexadecimal
     34  *    chars (no terminating zero)
     35  *
     36  * 3/ then, it uses recvmsg to receive file descriptors from the
     37  *    daemon. each incoming file descriptor is a pass-through to
     38  *    a given JDWP debugger, that can be used to read the usual
     39  *    JDWP-handshake, etc...
     40  */
     41 
     42 #define kInputBufferSize    8192
     43 
     44 #define kMagicHandshake     "JDWP-Handshake"
     45 #define kMagicHandshakeLen  (sizeof(kMagicHandshake)-1)
     46 
     47 #define kJdwpControlName    "\0jdwp-control"
     48 #define kJdwpControlNameLen (sizeof(kJdwpControlName)-1)
     49 
     50 struct JdwpNetState : public JdwpNetStateBase {
     51     int                 controlSock;
     52     bool                awaitingHandshake;
     53     bool                shuttingDown;
     54     int                 wakeFds[2];
     55 
     56     int                 inputCount;
     57     unsigned char       inputBuffer[kInputBufferSize];
     58 
     59     socklen_t           controlAddrLen;
     60     union {
     61         struct sockaddr_un  controlAddrUn;
     62         struct sockaddr     controlAddrPlain;
     63     } controlAddr;
     64 
     65     JdwpNetState()
     66     {
     67         controlSock = -1;
     68         awaitingHandshake = false;
     69         shuttingDown = false;
     70         wakeFds[0] = -1;
     71         wakeFds[1] = -1;
     72 
     73         inputCount = 0;
     74 
     75         controlAddr.controlAddrUn.sun_family = AF_UNIX;
     76         controlAddrLen = sizeof(controlAddr.controlAddrUn.sun_family) +
     77                 kJdwpControlNameLen;
     78         memcpy(controlAddr.controlAddrUn.sun_path, kJdwpControlName,
     79                 kJdwpControlNameLen);
     80     }
     81 };
     82 
     83 static void
     84 adbStateFree( JdwpNetState*  netState )
     85 {
     86     if (netState == NULL)
     87         return;
     88 
     89     if (netState->clientSock >= 0) {
     90         shutdown(netState->clientSock, SHUT_RDWR);
     91         close(netState->clientSock);
     92     }
     93     if (netState->controlSock >= 0) {
     94         shutdown(netState->controlSock, SHUT_RDWR);
     95         close(netState->controlSock);
     96     }
     97     if (netState->wakeFds[0] >= 0) {
     98         close(netState->wakeFds[0]);
     99         netState->wakeFds[0] = -1;
    100     }
    101     if (netState->wakeFds[1] >= 0) {
    102         close(netState->wakeFds[1]);
    103         netState->wakeFds[1] = -1;
    104     }
    105 
    106     delete netState;
    107 }
    108 
    109 /*
    110  * Do initial prep work, e.g. binding to ports and opening files.  This
    111  * runs in the main thread, before the JDWP thread starts, so it shouldn't
    112  * do anything that might block forever.
    113  */
    114 static bool startup(struct JdwpState* state, const JdwpStartupParams* pParams)
    115 {
    116     JdwpNetState*  netState;
    117 
    118     ALOGV("ADB transport startup");
    119 
    120     state->netState = netState = new JdwpNetState;
    121     if (netState == NULL)
    122         return false;
    123 
    124     return true;
    125 }
    126 
    127 /*
    128  * Receive a file descriptor from ADB.  The fd can be used to communicate
    129  * directly with a debugger or DDMS.
    130  *
    131  * Returns the file descriptor on success.  On failure, returns -1 and
    132  * closes netState->controlSock.
    133  */
    134 static int  receiveClientFd(JdwpNetState*  netState)
    135 {
    136     struct msghdr    msg;
    137     struct cmsghdr*  cmsg;
    138     struct iovec     iov;
    139     char             dummy = '!';
    140     union {
    141         struct cmsghdr cm;
    142         char buffer[CMSG_SPACE(sizeof(int))];
    143     } cm_un;
    144     int              ret;
    145 
    146     iov.iov_base       = &dummy;
    147     iov.iov_len        = 1;
    148     msg.msg_name       = NULL;
    149     msg.msg_namelen    = 0;
    150     msg.msg_iov        = &iov;
    151     msg.msg_iovlen     = 1;
    152     msg.msg_flags      = 0;
    153     msg.msg_control    = cm_un.buffer;
    154     msg.msg_controllen = sizeof(cm_un.buffer);
    155 
    156     cmsg = CMSG_FIRSTHDR(&msg);
    157     cmsg->cmsg_len   = msg.msg_controllen;
    158     cmsg->cmsg_level = SOL_SOCKET;
    159     cmsg->cmsg_type  = SCM_RIGHTS;
    160     ((int*)(void*)CMSG_DATA(cmsg))[0] = -1;
    161 
    162     do {
    163         ret = recvmsg(netState->controlSock, &msg, 0);
    164     } while (ret < 0 && errno == EINTR);
    165 
    166     if (ret <= 0) {
    167         if (ret < 0) {
    168             ALOGW("receiving file descriptor from ADB failed (socket %d): %s",
    169                  netState->controlSock, strerror(errno));
    170         }
    171         close(netState->controlSock);
    172         netState->controlSock = -1;
    173         return -1;
    174     }
    175 
    176     return ((int*)(void*)CMSG_DATA(cmsg))[0];
    177 }
    178 
    179 /*
    180  * Block forever, waiting for a debugger to connect to us.  Called from the
    181  * JDWP thread.
    182  *
    183  * This needs to un-block and return "false" if the VM is shutting down.  It
    184  * should return "true" when it successfully accepts a connection.
    185  */
    186 static bool acceptConnection(struct JdwpState* state)
    187 {
    188     JdwpNetState*  netState = state->netState;
    189     int retryCount = 0;
    190 
    191     /* first, ensure that we get a connection to the ADB daemon */
    192 
    193 retry:
    194     if (netState->shuttingDown)
    195         return false;
    196 
    197     if (netState->controlSock < 0) {
    198         int        sleep_ms     = 500;
    199         const int  sleep_max_ms = 2*1000;
    200         char       buff[5];
    201 
    202         netState->controlSock = socket(PF_UNIX, SOCK_STREAM, 0);
    203         if (netState->controlSock < 0) {
    204             ALOGE("Could not create ADB control socket:%s",
    205                  strerror(errno));
    206             return false;
    207         }
    208 
    209         if (pipe(netState->wakeFds) < 0) {
    210             ALOGE("pipe failed");
    211             return false;
    212         }
    213 
    214         snprintf(buff, sizeof(buff), "%04x", getpid());
    215         buff[4] = 0;
    216 
    217         for (;;) {
    218             /*
    219              * If adbd isn't running, because USB debugging was disabled or
    220              * perhaps the system is restarting it for "adb root", the
    221              * connect() will fail.  We loop here forever waiting for it
    222              * to come back.
    223              *
    224              * Waking up and polling every couple of seconds is generally a
    225              * bad thing to do, but we only do this if the application is
    226              * debuggable *and* adbd isn't running.  Still, for the sake
    227              * of battery life, we should consider timing out and giving
    228              * up after a few minutes in case somebody ships an app with
    229              * the debuggable flag set.
    230              */
    231             int  ret = connect(netState->controlSock,
    232                                &netState->controlAddr.controlAddrPlain,
    233                                netState->controlAddrLen);
    234             if (!ret) {
    235                 if (!socket_peer_is_trusted(netState->controlSock)) {
    236                     if (shutdown(netState->controlSock, SHUT_RDWR)) {
    237                         ALOGE("trouble shutting down socket: %s", strerror(errno));
    238                     }
    239                     return false;
    240                 }
    241 
    242                 /* now try to send our pid to the ADB daemon */
    243                 do {
    244                     ret = send( netState->controlSock, buff, 4, 0 );
    245                 } while (ret < 0 && errno == EINTR);
    246 
    247                 if (ret >= 0) {
    248                     ALOGV("PID sent as '%.*s' to ADB", 4, buff);
    249                     break;
    250                 }
    251 
    252                 ALOGE("Weird, can't send JDWP process pid to ADB: %s",
    253                      strerror(errno));
    254                 return false;
    255             }
    256             ALOGV("Can't connect to ADB control socket:%s",
    257                  strerror(errno));
    258 
    259             usleep( sleep_ms*1000 );
    260 
    261             sleep_ms += (sleep_ms >> 1);
    262             if (sleep_ms > sleep_max_ms)
    263                 sleep_ms = sleep_max_ms;
    264 
    265             if (netState->shuttingDown)
    266                 return false;
    267         }
    268     }
    269 
    270     ALOGV("trying to receive file descriptor from ADB");
    271     /* now we can receive a client file descriptor */
    272     netState->clientSock = receiveClientFd(netState);
    273     if (netState->shuttingDown)
    274         return false;       // suppress logs and additional activity
    275 
    276     if (netState->clientSock < 0) {
    277         if (++retryCount > 5) {
    278             ALOGE("adb connection max retries exceeded");
    279             return false;
    280         }
    281         goto retry;
    282     } else {
    283         ALOGV("received file descriptor %d from ADB", netState->clientSock);
    284         netState->awaitingHandshake = 1;
    285         netState->inputCount = 0;
    286         return true;
    287     }
    288 }
    289 
    290 /*
    291  * Connect out to a debugger (for server=n).  Not required.
    292  */
    293 static bool establishConnection(struct JdwpState* state)
    294 {
    295     return false;
    296 }
    297 
    298 /*
    299  * Close a connection from a debugger (which may have already dropped us).
    300  * Only called from the JDWP thread.
    301  */
    302 static void closeConnection(struct JdwpState* state)
    303 {
    304     JdwpNetState* netState;
    305 
    306     assert(state != NULL && state->netState != NULL);
    307 
    308     netState = state->netState;
    309     if (netState->clientSock < 0)
    310         return;
    311 
    312     ALOGV("+++ closed JDWP <-> ADB connection");
    313 
    314     close(netState->clientSock);
    315     netState->clientSock = -1;
    316 }
    317 
    318 /*
    319  * Close all network stuff, including the socket we use to listen for
    320  * new connections.
    321  *
    322  * May be called from a non-JDWP thread, e.g. when the VM is shutting down.
    323  */
    324 static void adbStateShutdown(struct JdwpNetState* netState)
    325 {
    326     int  controlSock;
    327     int  clientSock;
    328 
    329     if (netState == NULL)
    330         return;
    331 
    332     netState->shuttingDown = true;
    333 
    334     clientSock = netState->clientSock;
    335     if (clientSock >= 0) {
    336         shutdown(clientSock, SHUT_RDWR);
    337         netState->clientSock = -1;
    338     }
    339 
    340     controlSock = netState->controlSock;
    341     if (controlSock >= 0) {
    342         shutdown(controlSock, SHUT_RDWR);
    343         netState->controlSock = -1;
    344     }
    345 
    346     if (netState->wakeFds[1] >= 0) {
    347         ALOGV("+++ writing to wakePipe");
    348         TEMP_FAILURE_RETRY(write(netState->wakeFds[1], "", 1));
    349     }
    350 }
    351 
    352 static void netShutdown(JdwpState* state)
    353 {
    354     adbStateShutdown(state->netState);
    355 }
    356 
    357 /*
    358  * Free up anything we put in state->netState.  This is called after
    359  * "netShutdown", after the JDWP thread has stopped.
    360  */
    361 static void netFree(struct JdwpState* state)
    362 {
    363     JdwpNetState*  netState = state->netState;
    364 
    365     adbStateFree(netState);
    366 }
    367 
    368 /*
    369  * Is a debugger connected to us?
    370  */
    371 static bool isConnected(struct JdwpState* state)
    372 {
    373     return (state->netState != NULL   &&
    374             state->netState->clientSock >= 0);
    375 }
    376 
    377 /*
    378  * Are we still waiting for the JDWP handshake?
    379  */
    380 static bool awaitingHandshake(struct JdwpState* state)
    381 {
    382     return state->netState->awaitingHandshake;
    383 }
    384 
    385 /*
    386  * Figure out if we have a full packet in the buffer.
    387  */
    388 static bool haveFullPacket(JdwpNetState* netState)
    389 {
    390     long length;
    391 
    392     if (netState->awaitingHandshake)
    393         return (netState->inputCount >= (int) kMagicHandshakeLen);
    394 
    395     if (netState->inputCount < 4)
    396         return false;
    397 
    398     length = get4BE(netState->inputBuffer);
    399     return (netState->inputCount >= length);
    400 }
    401 
    402 /*
    403  * Consume bytes from the buffer.
    404  *
    405  * This would be more efficient with a circular buffer.  However, we're
    406  * usually only going to find one packet, which is trivial to handle.
    407  */
    408 static void consumeBytes(JdwpNetState* netState, int count)
    409 {
    410     assert(count > 0);
    411     assert(count <= netState->inputCount);
    412 
    413     if (count == netState->inputCount) {
    414         netState->inputCount = 0;
    415         return;
    416     }
    417 
    418     memmove(netState->inputBuffer, netState->inputBuffer + count,
    419         netState->inputCount - count);
    420     netState->inputCount -= count;
    421 }
    422 
    423 /*
    424  * Handle a packet.  Returns "false" if we encounter a connection-fatal error.
    425  */
    426 static bool handlePacket(JdwpState* state)
    427 {
    428     JdwpNetState* netState = state->netState;
    429     const unsigned char* buf = netState->inputBuffer;
    430     JdwpReqHeader hdr;
    431     u4 length, id;
    432     u1 flags, cmdSet, cmd;
    433     u2 error;
    434     bool reply;
    435     int dataLen;
    436 
    437     cmd = cmdSet = 0;       // shut up gcc
    438 
    439     length = read4BE(&buf);
    440     id = read4BE(&buf);
    441     flags = read1(&buf);
    442     if ((flags & kJDWPFlagReply) != 0) {
    443         reply = true;
    444         error = read2BE(&buf);
    445     } else {
    446         reply = false;
    447         cmdSet = read1(&buf);
    448         cmd = read1(&buf);
    449     }
    450 
    451     assert((int) length <= netState->inputCount);
    452     dataLen = length - (buf - netState->inputBuffer);
    453 
    454     if (!reply) {
    455         ExpandBuf* pReply = expandBufAlloc();
    456 
    457         hdr.length = length;
    458         hdr.id = id;
    459         hdr.cmdSet = cmdSet;
    460         hdr.cmd = cmd;
    461         dvmJdwpProcessRequest(state, &hdr, buf, dataLen, pReply);
    462         if (expandBufGetLength(pReply) > 0) {
    463             ssize_t cc = netState->writePacket(pReply);
    464 
    465             if (cc != (ssize_t) expandBufGetLength(pReply)) {
    466                 ALOGE("Failed sending reply to debugger: %s", strerror(errno));
    467                 expandBufFree(pReply);
    468                 return false;
    469             }
    470         } else {
    471             ALOGW("No reply created for set=%d cmd=%d", cmdSet, cmd);
    472         }
    473         expandBufFree(pReply);
    474     } else {
    475         ALOGV("reply?!");
    476         assert(false);
    477     }
    478 
    479     ALOGV("----------");
    480 
    481     consumeBytes(netState, length);
    482     return true;
    483 }
    484 
    485 /*
    486  * Process incoming data.  If no data is available, this will block until
    487  * some arrives.
    488  *
    489  * If we get a full packet, handle it.
    490  *
    491  * To take some of the mystery out of life, we want to reject incoming
    492  * connections if we already have a debugger attached.  If we don't, the
    493  * debugger will just mysteriously hang until it times out.  We could just
    494  * close the listen socket, but there's a good chance we won't be able to
    495  * bind to the same port again, which would confuse utilities.
    496  *
    497  * Returns "false" on error (indicating that the connection has been severed),
    498  * "true" if things are still okay.
    499  */
    500 static bool processIncoming(JdwpState* state)
    501 {
    502     JdwpNetState* netState = state->netState;
    503     int readCount;
    504 
    505     assert(netState->clientSock >= 0);
    506 
    507     if (!haveFullPacket(netState)) {
    508         /* read some more, looping until we have data */
    509         errno = 0;
    510         while (1) {
    511             int selCount;
    512             fd_set readfds;
    513             int maxfd = -1;
    514             int fd;
    515 
    516             FD_ZERO(&readfds);
    517 
    518             /* configure fds; note these may get zapped by another thread */
    519             fd = netState->controlSock;
    520             if (fd >= 0) {
    521                 FD_SET(fd, &readfds);
    522                 if (maxfd < fd)
    523                     maxfd = fd;
    524             }
    525             fd = netState->clientSock;
    526             if (fd >= 0) {
    527                 FD_SET(fd, &readfds);
    528                 if (maxfd < fd)
    529                     maxfd = fd;
    530             }
    531             fd = netState->wakeFds[0];
    532             if (fd >= 0) {
    533                 FD_SET(fd, &readfds);
    534                 if (maxfd < fd)
    535                     maxfd = fd;
    536             } else {
    537                 ALOGI("NOTE: entering select w/o wakepipe");
    538             }
    539 
    540             if (maxfd < 0) {
    541                 ALOGV("+++ all fds are closed");
    542                 return false;
    543             }
    544 
    545             /*
    546              * Select blocks until it sees activity on the file descriptors.
    547              * Closing the local file descriptor does not count as activity,
    548              * so we can't rely on that to wake us up (it works for read()
    549              * and accept(), but not select()).
    550              *
    551              * We can do one of three things: (1) send a signal and catch
    552              * EINTR, (2) open an additional fd ("wakePipe") and write to
    553              * it when it's time to exit, or (3) time out periodically and
    554              * re-issue the select.  We're currently using #2, as it's more
    555              * reliable than #1 and generally better than #3.  Wastes two fds.
    556              */
    557             selCount = select(maxfd+1, &readfds, NULL, NULL, NULL);
    558             if (selCount < 0) {
    559                 if (errno == EINTR)
    560                     continue;
    561                 ALOGE("select failed: %s", strerror(errno));
    562                 goto fail;
    563             }
    564 
    565             if (netState->wakeFds[0] >= 0 &&
    566                 FD_ISSET(netState->wakeFds[0], &readfds))
    567             {
    568                 ALOGD("Got wake-up signal, bailing out of select");
    569                 goto fail;
    570             }
    571             if (netState->controlSock >= 0 &&
    572                 FD_ISSET(netState->controlSock, &readfds))
    573             {
    574                 int  sock = receiveClientFd(netState);
    575                 if (sock >= 0) {
    576                     ALOGI("Ignoring second debugger -- accepting and dropping");
    577                     close(sock);
    578                 } else {
    579                     assert(netState->controlSock < 0);
    580                     /*
    581                      * Remote side most likely went away, so our next read
    582                      * on netState->clientSock will fail and throw us out
    583                      * of the loop.
    584                      */
    585                 }
    586             }
    587             if (netState->clientSock >= 0 &&
    588                 FD_ISSET(netState->clientSock, &readfds))
    589             {
    590                 readCount = read(netState->clientSock,
    591                                 netState->inputBuffer + netState->inputCount,
    592                     sizeof(netState->inputBuffer) - netState->inputCount);
    593                 if (readCount < 0) {
    594                     /* read failed */
    595                     if (errno != EINTR)
    596                         goto fail;
    597                     ALOGD("+++ EINTR hit");
    598                     return true;
    599                 } else if (readCount == 0) {
    600                     /* EOF hit -- far end went away */
    601                     ALOGV("+++ peer disconnected");
    602                     goto fail;
    603                 } else
    604                     break;
    605             }
    606         }
    607 
    608         netState->inputCount += readCount;
    609         if (!haveFullPacket(netState))
    610             return true;        /* still not there yet */
    611     }
    612 
    613     /*
    614      * Special-case the initial handshake.  For some bizarre reason we're
    615      * expected to emulate bad tty settings by echoing the request back
    616      * exactly as it was sent.  Note the handshake is always initiated by
    617      * the debugger, no matter who connects to whom.
    618      *
    619      * Other than this one case, the protocol [claims to be] stateless.
    620      */
    621     if (netState->awaitingHandshake) {
    622         int cc;
    623 
    624         if (memcmp(netState->inputBuffer,
    625                 kMagicHandshake, kMagicHandshakeLen) != 0)
    626         {
    627             ALOGE("ERROR: bad handshake '%.14s'", netState->inputBuffer);
    628             goto fail;
    629         }
    630 
    631         errno = 0;
    632         cc = TEMP_FAILURE_RETRY(write(netState->clientSock, netState->inputBuffer,
    633                                       kMagicHandshakeLen));
    634         if (cc != kMagicHandshakeLen) {
    635             ALOGE("Failed writing handshake bytes: %s (%d of %d)",
    636                 strerror(errno), cc, (int) kMagicHandshakeLen);
    637             goto fail;
    638         }
    639 
    640         consumeBytes(netState, kMagicHandshakeLen);
    641         netState->awaitingHandshake = false;
    642         ALOGV("+++ handshake complete");
    643         return true;
    644     }
    645 
    646     /*
    647      * Handle this packet.
    648      */
    649     return handlePacket(state);
    650 
    651 fail:
    652     closeConnection(state);
    653     return false;
    654 }
    655 
    656 /*
    657  * Send a request.
    658  *
    659  * The entire packet must be sent with a single write() call to avoid
    660  * threading issues.
    661  *
    662  * Returns "true" if it was sent successfully.
    663  */
    664 static bool sendRequest(JdwpState* state, ExpandBuf* pReq)
    665 {
    666     JdwpNetState* netState = state->netState;
    667 
    668     if (netState->clientSock < 0) {
    669         /* can happen with some DDMS events */
    670         ALOGV("NOT sending request -- no debugger is attached");
    671         return false;
    672     }
    673 
    674     errno = 0;
    675 
    676     ssize_t cc = netState->writePacket(pReq);
    677 
    678     if (cc != (ssize_t) expandBufGetLength(pReq)) {
    679         ALOGE("Failed sending req to debugger: %s (%d of %d)",
    680             strerror(errno), (int) cc, (int) expandBufGetLength(pReq));
    681         return false;
    682     }
    683 
    684     return true;
    685 }
    686 
    687 /*
    688  * Send a request that was split into multiple buffers.
    689  *
    690  * The entire packet must be sent with a single writev() call to avoid
    691  * threading issues.
    692  *
    693  * Returns "true" if it was sent successfully.
    694  */
    695 static bool sendBufferedRequest(JdwpState* state, const struct iovec* iov,
    696     int iovcnt)
    697 {
    698     JdwpNetState* netState = state->netState;
    699 
    700     if (netState->clientSock < 0) {
    701         /* can happen with some DDMS events */
    702         ALOGV("NOT sending request -- no debugger is attached");
    703         return false;
    704     }
    705 
    706     size_t expected = 0;
    707     int i;
    708     for (i = 0; i < iovcnt; i++)
    709         expected += iov[i].iov_len;
    710 
    711     ssize_t actual = netState->writeBufferedPacket(iov, iovcnt);
    712 
    713     if ((size_t)actual != expected) {
    714         ALOGE("Failed sending b-req to debugger: %s (%d of %zu)",
    715             strerror(errno), (int) actual, expected);
    716         return false;
    717     }
    718 
    719     return true;
    720 }
    721 
    722 
    723 /*
    724  * Our functions.
    725  */
    726 static const JdwpTransport socketTransport = {
    727     startup,
    728     acceptConnection,
    729     establishConnection,
    730     closeConnection,
    731     netShutdown,
    732     netFree,
    733     isConnected,
    734     awaitingHandshake,
    735     processIncoming,
    736     sendRequest,
    737     sendBufferedRequest
    738 };
    739 
    740 /*
    741  * Return our set.
    742  */
    743 const JdwpTransport* dvmJdwpAndroidAdbTransport()
    744 {
    745     return &socketTransport;
    746 }
    747