jdwp_service.c 20 KB

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