jdwp_service.c
来自「Android 一些工具」· C语言 代码 · 共 710 行 · 第 1/2 页
C
710 行
if (--proc->out_count == 0) fdevent_del( proc->fde, FDE_WRITE ); } }}intcreate_jdwp_connection_fd(int pid){ JdwpProcess* proc = _jdwp_list.next; D("looking for pid %d in JDWP process list\n", pid); for ( ; proc != &_jdwp_list; proc = proc->next ) { if (proc->pid == pid) { goto FoundIt; } } D("search failed !!\n"); return -1;FoundIt: { int fds[2]; if (proc->out_count >= MAX_OUT_FDS) { D("%s: too many pending JDWP connection for pid %d\n", __FUNCTION__, pid); return -1; } if (adb_socketpair(fds) < 0) { D("%s: socket pair creation failed: %s\n", __FUNCTION__, strerror(errno)); return -1; } proc->out_fds[ proc->out_count ] = fds[1]; if (++proc->out_count == 1) fdevent_add( proc->fde, FDE_WRITE ); return fds[0]; }}/** VM DEBUG CONTROL SOCKET ** ** we do implement a custom asocket to receive the data **//* name of the debug control Unix socket */#define JDWP_CONTROL_NAME "\0jdwp-control"#define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME)-1)typedef struct { int listen_socket; fdevent* fde;} JdwpControl;static voidjdwp_control_event(int s, unsigned events, void* user);static intjdwp_control_init( JdwpControl* control, const char* sockname, int socknamelen ){ struct sockaddr_un addr; socklen_t addrlen; int s; int maxpath = sizeof(addr.sun_path); int pathlen = socknamelen; if (pathlen >= maxpath) { D( "vm debug control socket name too long (%d extra chars)\n", pathlen+1-maxpath ); return -1; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; memcpy(addr.sun_path, sockname, socknamelen); s = socket( AF_UNIX, SOCK_STREAM, 0 ); if (s < 0) { D( "could not create vm debug control socket. %d: %s\n", errno, strerror(errno)); return -1; } addrlen = (pathlen + sizeof(addr.sun_family)); if (bind(s, (struct sockaddr*)&addr, addrlen) < 0) { D( "could not bind vm debug control socket: %d: %s\n", errno, strerror(errno) ); adb_close(s); return -1; } if ( listen(s, 4) < 0 ) { D("listen failed in jdwp control socket: %d: %s\n", errno, strerror(errno)); adb_close(s); return -1; } control->listen_socket = s; control->fde = fdevent_create(s, jdwp_control_event, control); if (control->fde == NULL) { D( "could not create fdevent for jdwp control socket\n" ); adb_close(s); return -1; } /* only wait for incoming connections */ fdevent_add(control->fde, FDE_READ); D("jdwp control socket started (%d)\n", control->listen_socket); return 0;}static voidjdwp_control_event( int s, unsigned events, void* _control ){ JdwpControl* control = (JdwpControl*) _control; if (events & FDE_READ) { struct sockaddr addr; socklen_t addrlen = sizeof(addr); int s = -1; JdwpProcess* proc; do { s = adb_socket_accept( control->listen_socket, &addr, &addrlen ); if (s < 0) { if (errno == EINTR) continue; if (errno == ECONNABORTED) { /* oops, the JDWP process died really quick */ D("oops, the JDWP process died really quick\n"); return; } /* the socket is probably closed ? */ D( "weird accept() failed on jdwp control socket: %s\n", strerror(errno) ); return; } } while (s < 0); proc = jdwp_process_alloc( s ); if (proc == NULL) return; }}static JdwpControl _jdwp_control;/** "jdwp" local service implementation ** this simply returns the list of known JDWP process pids **/typedef struct { asocket socket; int pass;} JdwpSocket;static voidjdwp_socket_close( asocket* s ){ asocket* peer = s->peer; remove_socket(s); if (peer) { peer->peer = NULL; peer->close(peer); } free(s);}static intjdwp_socket_enqueue( asocket* s, apacket* p ){ /* you can't write to this asocket */ put_apacket(p); s->peer->close(s->peer); return -1;}static voidjdwp_socket_ready( asocket* s ){ JdwpSocket* jdwp = (JdwpSocket*)s; asocket* peer = jdwp->socket.peer; /* on the first call, send the list of pids, * on the second one, close the connection */ if (jdwp->pass == 0) { apacket* p = get_apacket(); p->len = jdwp_process_list((char*)p->data, MAX_PAYLOAD); peer->enqueue(peer, p); jdwp->pass = 1; } else { peer->close(peer); }}asocket*create_jdwp_service_socket( void ){ JdwpSocket* s = calloc(sizeof(*s),1); if (s == NULL) return NULL; install_local_socket(&s->socket); s->socket.ready = jdwp_socket_ready; s->socket.enqueue = jdwp_socket_enqueue; s->socket.close = jdwp_socket_close; s->pass = 0; return &s->socket;}/** "track-jdwp" local service implementation ** this periodically sends the list of known JDWP process pids ** to the client... **/typedef struct JdwpTracker JdwpTracker;struct JdwpTracker { asocket socket; JdwpTracker* next; JdwpTracker* prev; int need_update;};static JdwpTracker _jdwp_trackers_list;static voidjdwp_process_list_updated(void){ char buffer[1024]; int len; JdwpTracker* t = _jdwp_trackers_list.next; len = jdwp_process_list_msg(buffer, sizeof(buffer)); for ( ; t != &_jdwp_trackers_list; t = t->next ) { apacket* p = get_apacket(); asocket* peer = t->socket.peer; memcpy(p->data, buffer, len); p->len = len; peer->enqueue( peer, p ); }}static voidjdwp_tracker_close( asocket* s ){ JdwpTracker* tracker = (JdwpTracker*) s; asocket* peer = s->peer; if (peer) { peer->peer = NULL; peer->close(peer); } remove_socket(s); tracker->prev->next = tracker->next; tracker->next->prev = tracker->prev; free(s);}static voidjdwp_tracker_ready( asocket* s ){ JdwpTracker* t = (JdwpTracker*) s; if (t->need_update) { apacket* p = get_apacket(); t->need_update = 0; p->len = jdwp_process_list_msg((char*)p->data, sizeof(p->data)); s->peer->enqueue(s->peer, p); }}static intjdwp_tracker_enqueue( asocket* s, apacket* p ){ /* you can't write to this socket */ put_apacket(p); s->peer->close(s->peer); return -1;}asocket*create_jdwp_tracker_service_socket( void ){ JdwpTracker* t = calloc(sizeof(*t),1); if (t == NULL) return NULL; t->next = &_jdwp_trackers_list; t->prev = t->next->prev; t->next->prev = t; t->prev->next = t; install_local_socket(&t->socket); t->socket.ready = jdwp_tracker_ready; t->socket.enqueue = jdwp_tracker_enqueue; t->socket.close = jdwp_tracker_close; t->need_update = 1; return &t->socket;}intinit_jdwp(void){ _jdwp_list.next = &_jdwp_list; _jdwp_list.prev = &_jdwp_list; _jdwp_trackers_list.next = &_jdwp_trackers_list; _jdwp_trackers_list.prev = &_jdwp_trackers_list; return jdwp_control_init( &_jdwp_control, JDWP_CONTROL_NAME, JDWP_CONTROL_NAME_LEN );}#endif /* !ADB_HOST */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?