Loading adb/Android.bp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -344,6 +344,7 @@ cc_library_static { generated_headers: ["platform_tools_version"], generated_headers: ["platform_tools_version"], static_libs: [ static_libs: [ "libadbconnection_server", "libdiagnose_usb", "libdiagnose_usb", ], ], Loading Loading @@ -395,6 +396,7 @@ cc_library { ], ], static_libs: [ static_libs: [ "libadbconnection_server", "libadbd_core", "libadbd_core", "libdiagnose_usb", "libdiagnose_usb", ], ], Loading Loading @@ -531,6 +533,7 @@ cc_binary { }, }, static_libs: [ static_libs: [ "libadbconnection_server", "libadbd", "libadbd", "libadbd_services", "libadbd_services", "libasyncio", "libasyncio", Loading adb/daemon/include/adbd/usb.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ * limitations under the License. * limitations under the License. */ */ #include <linux/usb/functionfs.h> #include <atomic> #include <atomic> #include <condition_variable> #include <condition_variable> #include <mutex> #include <mutex> Loading adb/daemon/jdwp_service.cpp +32 −126 Original line number Original line Diff line number Diff line Loading @@ -30,15 +30,21 @@ #include <list> #include <list> #include <memory> #include <memory> #include <thread> #include <vector> #include <vector> #include <adbconnection/server.h> #include <android-base/cmsg.h> #include <android-base/cmsg.h> #include <android-base/unique_fd.h> #include "adb.h" #include "adb.h" #include "adb_io.h" #include "adb_io.h" #include "adb_unique_fd.h" #include "adb_unique_fd.h" #include "adb_utils.h" #include "adb_utils.h" using android::base::borrowed_fd; using android::base::unique_fd; /* here's how these things work. /* here's how these things work. when adbd starts, it creates a unix server socket when adbd starts, it creates a unix server socket Loading Loading @@ -133,16 +139,16 @@ struct JdwpProcess; static auto& _jdwp_list = *new std::list<std::unique_ptr<JdwpProcess>>(); static auto& _jdwp_list = *new std::list<std::unique_ptr<JdwpProcess>>(); struct JdwpProcess { struct JdwpProcess { explicit JdwpProcess(int socket) { JdwpProcess(unique_fd socket, pid_t pid) { CHECK(pid != 0); this->socket = socket; this->socket = socket; this->fde = fdevent_create(socket, jdwp_process_event, this); this->pid = pid; this->fde = fdevent_create(socket.release(), jdwp_process_event, this); if (!this->fde) { if (!this->fde) { LOG(FATAL) << "could not create fdevent for new JDWP process"; LOG(FATAL) << "could not create fdevent for new JDWP process"; } } /* start by waiting for the PID */ fdevent_add(this->fde, FDE_READ); } } ~JdwpProcess() { ~JdwpProcess() { Loading @@ -160,18 +166,12 @@ struct JdwpProcess { } } void RemoveFromList() { void RemoveFromList() { if (this->pid >= 0) { D("removing pid %d from jdwp process list", this->pid); } else { D("removing transient JdwpProcess from list"); } auto pred = [this](const auto& proc) { return proc.get() == this; }; auto pred = [this](const auto& proc) { return proc.get() == this; }; _jdwp_list.remove_if(pred); _jdwp_list.remove_if(pred); } } borrowed_fd socket = -1; int32_t pid = -1; int32_t pid = -1; int socket = -1; fdevent* fde = nullptr; fdevent* fde = nullptr; std::vector<unique_fd> out_fds; std::vector<unique_fd> out_fds; Loading @@ -181,11 +181,6 @@ static size_t jdwp_process_list(char* buffer, size_t bufferlen) { std::string temp; std::string temp; for (auto& proc : _jdwp_list) { for (auto& proc : _jdwp_list) { /* skip transient connections */ if (proc->pid < 0) { continue; } std::string next = std::to_string(proc->pid) + "\n"; std::string next = std::to_string(proc->pid) + "\n"; if (temp.length() + next.length() > bufferlen) { if (temp.length() + next.length() > bufferlen) { D("truncating JDWP process list (max len = %zu)", bufferlen); D("truncating JDWP process list (max len = %zu)", bufferlen); Loading Loading @@ -214,25 +209,13 @@ static size_t jdwp_process_list_msg(char* buffer, size_t bufferlen) { static void jdwp_process_event(int socket, unsigned events, void* _proc) { static void jdwp_process_event(int socket, unsigned events, void* _proc) { JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(_proc); JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(_proc); CHECK_EQ(socket, proc->socket); CHECK_EQ(socket, proc->socket.get()); if (events & FDE_READ) { if (events & FDE_READ) { if (proc->pid < 0) { ssize_t rc = TEMP_FAILURE_RETRY(recv(socket, &proc->pid, sizeof(proc->pid), 0)); if (rc != sizeof(proc->pid)) { D("failed to read jdwp pid: rc = %zd, errno = %s", rc, strerror(errno)); goto CloseProcess; } /* all is well, keep reading to detect connection closure */ D("Adding pid %d to jdwp process list", proc->pid); jdwp_process_list_updated(); } else { // We already have the PID, if we can read from the socket, we've probably hit EOF. // We already have the PID, if we can read from the socket, we've probably hit EOF. D("terminating JDWP connection %d", proc->pid); D("terminating JDWP connection %d", proc->pid); goto CloseProcess; goto CloseProcess; } } } if (events & FDE_WRITE) { if (events & FDE_WRITE) { D("trying to send fd to JDWP process (count = %zu)", proc->out_fds.size()); D("trying to send fd to JDWP process (count = %zu)", proc->out_fds.size()); Loading Loading @@ -284,98 +267,6 @@ unique_fd create_jdwp_connection_fd(int pid) { return unique_fd{}; return unique_fd{}; } } /** 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) struct JdwpControl { int listen_socket; fdevent* fde; }; static JdwpControl _jdwp_control; static void jdwp_control_event(int s, unsigned events, void* user); static int jdwp_control_init(JdwpControl* control, const char* sockname, int socknamelen) { sockaddr_un addr; socklen_t addrlen; int maxpath = sizeof(addr.sun_path); int pathlen = socknamelen; if (pathlen >= maxpath) { D("vm debug control socket name too long (%d extra chars)", pathlen + 1 - maxpath); return -1; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; memcpy(addr.sun_path, sockname, socknamelen); unique_fd s(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0)); if (s < 0) { D("could not create vm debug control socket. %d: %s", errno, strerror(errno)); return -1; } addrlen = pathlen + sizeof(addr.sun_family); if (bind(s.get(), reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) { D("could not bind vm debug control socket: %d: %s", errno, strerror(errno)); return -1; } if (listen(s.get(), 4) < 0) { D("listen failed in jdwp control socket: %d: %s", errno, strerror(errno)); return -1; } control->listen_socket = s.release(); control->fde = fdevent_create(control->listen_socket, jdwp_control_event, control); if (control->fde == nullptr) { D("could not create fdevent for jdwp control socket"); return -1; } /* only wait for incoming connections */ fdevent_add(control->fde, FDE_READ); D("jdwp control socket started (%d)", control->listen_socket); return 0; } static void jdwp_control_event(int fd, unsigned events, void* _control) { JdwpControl* control = (JdwpControl*)_control; CHECK_EQ(fd, control->listen_socket); if (events & FDE_READ) { int s = adb_socket_accept(control->listen_socket, nullptr, nullptr); if (s < 0) { if (errno == ECONNABORTED) { /* oops, the JDWP process died really quick */ D("oops, the JDWP process died really quick"); return; } else { /* the socket is probably closed ? */ D("weird accept() failed on jdwp control socket: %s", strerror(errno)); return; } } auto proc = std::make_unique<JdwpProcess>(s); if (!proc) { LOG(FATAL) << "failed to allocate JdwpProcess"; } _jdwp_list.emplace_back(std::move(proc)); } } /** "jdwp" local service implementation /** "jdwp" local service implementation ** this simply returns the list of known JDWP process pids ** this simply returns the list of known JDWP process pids **/ **/ Loading Loading @@ -526,7 +417,22 @@ asocket* create_jdwp_tracker_service_socket(void) { } } int init_jdwp(void) { int init_jdwp(void) { return jdwp_control_init(&_jdwp_control, JDWP_CONTROL_NAME, JDWP_CONTROL_NAME_LEN); std::thread([]() { adb_thread_setname("jdwp control"); adbconnection_listen([](int fd, pid_t pid) { LOG(INFO) << "jdwp connection from " << pid; fdevent_run_on_main_thread([fd, pid] { unique_fd ufd(fd); auto proc = std::make_unique<JdwpProcess>(std::move(ufd), pid); if (!proc) { LOG(FATAL) << "failed to allocate JdwpProcess"; } _jdwp_list.emplace_back(std::move(proc)); jdwp_process_list_updated(); }); }); }).detach(); return 0; } } #endif /* !ADB_HOST */ #endif /* !ADB_HOST */ Loading
adb/Android.bp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -344,6 +344,7 @@ cc_library_static { generated_headers: ["platform_tools_version"], generated_headers: ["platform_tools_version"], static_libs: [ static_libs: [ "libadbconnection_server", "libdiagnose_usb", "libdiagnose_usb", ], ], Loading Loading @@ -395,6 +396,7 @@ cc_library { ], ], static_libs: [ static_libs: [ "libadbconnection_server", "libadbd_core", "libadbd_core", "libdiagnose_usb", "libdiagnose_usb", ], ], Loading Loading @@ -531,6 +533,7 @@ cc_binary { }, }, static_libs: [ static_libs: [ "libadbconnection_server", "libadbd", "libadbd", "libadbd_services", "libadbd_services", "libasyncio", "libasyncio", Loading
adb/daemon/include/adbd/usb.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ * limitations under the License. * limitations under the License. */ */ #include <linux/usb/functionfs.h> #include <atomic> #include <atomic> #include <condition_variable> #include <condition_variable> #include <mutex> #include <mutex> Loading
adb/daemon/jdwp_service.cpp +32 −126 Original line number Original line Diff line number Diff line Loading @@ -30,15 +30,21 @@ #include <list> #include <list> #include <memory> #include <memory> #include <thread> #include <vector> #include <vector> #include <adbconnection/server.h> #include <android-base/cmsg.h> #include <android-base/cmsg.h> #include <android-base/unique_fd.h> #include "adb.h" #include "adb.h" #include "adb_io.h" #include "adb_io.h" #include "adb_unique_fd.h" #include "adb_unique_fd.h" #include "adb_utils.h" #include "adb_utils.h" using android::base::borrowed_fd; using android::base::unique_fd; /* here's how these things work. /* here's how these things work. when adbd starts, it creates a unix server socket when adbd starts, it creates a unix server socket Loading Loading @@ -133,16 +139,16 @@ struct JdwpProcess; static auto& _jdwp_list = *new std::list<std::unique_ptr<JdwpProcess>>(); static auto& _jdwp_list = *new std::list<std::unique_ptr<JdwpProcess>>(); struct JdwpProcess { struct JdwpProcess { explicit JdwpProcess(int socket) { JdwpProcess(unique_fd socket, pid_t pid) { CHECK(pid != 0); this->socket = socket; this->socket = socket; this->fde = fdevent_create(socket, jdwp_process_event, this); this->pid = pid; this->fde = fdevent_create(socket.release(), jdwp_process_event, this); if (!this->fde) { if (!this->fde) { LOG(FATAL) << "could not create fdevent for new JDWP process"; LOG(FATAL) << "could not create fdevent for new JDWP process"; } } /* start by waiting for the PID */ fdevent_add(this->fde, FDE_READ); } } ~JdwpProcess() { ~JdwpProcess() { Loading @@ -160,18 +166,12 @@ struct JdwpProcess { } } void RemoveFromList() { void RemoveFromList() { if (this->pid >= 0) { D("removing pid %d from jdwp process list", this->pid); } else { D("removing transient JdwpProcess from list"); } auto pred = [this](const auto& proc) { return proc.get() == this; }; auto pred = [this](const auto& proc) { return proc.get() == this; }; _jdwp_list.remove_if(pred); _jdwp_list.remove_if(pred); } } borrowed_fd socket = -1; int32_t pid = -1; int32_t pid = -1; int socket = -1; fdevent* fde = nullptr; fdevent* fde = nullptr; std::vector<unique_fd> out_fds; std::vector<unique_fd> out_fds; Loading @@ -181,11 +181,6 @@ static size_t jdwp_process_list(char* buffer, size_t bufferlen) { std::string temp; std::string temp; for (auto& proc : _jdwp_list) { for (auto& proc : _jdwp_list) { /* skip transient connections */ if (proc->pid < 0) { continue; } std::string next = std::to_string(proc->pid) + "\n"; std::string next = std::to_string(proc->pid) + "\n"; if (temp.length() + next.length() > bufferlen) { if (temp.length() + next.length() > bufferlen) { D("truncating JDWP process list (max len = %zu)", bufferlen); D("truncating JDWP process list (max len = %zu)", bufferlen); Loading Loading @@ -214,25 +209,13 @@ static size_t jdwp_process_list_msg(char* buffer, size_t bufferlen) { static void jdwp_process_event(int socket, unsigned events, void* _proc) { static void jdwp_process_event(int socket, unsigned events, void* _proc) { JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(_proc); JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(_proc); CHECK_EQ(socket, proc->socket); CHECK_EQ(socket, proc->socket.get()); if (events & FDE_READ) { if (events & FDE_READ) { if (proc->pid < 0) { ssize_t rc = TEMP_FAILURE_RETRY(recv(socket, &proc->pid, sizeof(proc->pid), 0)); if (rc != sizeof(proc->pid)) { D("failed to read jdwp pid: rc = %zd, errno = %s", rc, strerror(errno)); goto CloseProcess; } /* all is well, keep reading to detect connection closure */ D("Adding pid %d to jdwp process list", proc->pid); jdwp_process_list_updated(); } else { // We already have the PID, if we can read from the socket, we've probably hit EOF. // We already have the PID, if we can read from the socket, we've probably hit EOF. D("terminating JDWP connection %d", proc->pid); D("terminating JDWP connection %d", proc->pid); goto CloseProcess; goto CloseProcess; } } } if (events & FDE_WRITE) { if (events & FDE_WRITE) { D("trying to send fd to JDWP process (count = %zu)", proc->out_fds.size()); D("trying to send fd to JDWP process (count = %zu)", proc->out_fds.size()); Loading Loading @@ -284,98 +267,6 @@ unique_fd create_jdwp_connection_fd(int pid) { return unique_fd{}; return unique_fd{}; } } /** 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) struct JdwpControl { int listen_socket; fdevent* fde; }; static JdwpControl _jdwp_control; static void jdwp_control_event(int s, unsigned events, void* user); static int jdwp_control_init(JdwpControl* control, const char* sockname, int socknamelen) { sockaddr_un addr; socklen_t addrlen; int maxpath = sizeof(addr.sun_path); int pathlen = socknamelen; if (pathlen >= maxpath) { D("vm debug control socket name too long (%d extra chars)", pathlen + 1 - maxpath); return -1; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; memcpy(addr.sun_path, sockname, socknamelen); unique_fd s(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0)); if (s < 0) { D("could not create vm debug control socket. %d: %s", errno, strerror(errno)); return -1; } addrlen = pathlen + sizeof(addr.sun_family); if (bind(s.get(), reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) { D("could not bind vm debug control socket: %d: %s", errno, strerror(errno)); return -1; } if (listen(s.get(), 4) < 0) { D("listen failed in jdwp control socket: %d: %s", errno, strerror(errno)); return -1; } control->listen_socket = s.release(); control->fde = fdevent_create(control->listen_socket, jdwp_control_event, control); if (control->fde == nullptr) { D("could not create fdevent for jdwp control socket"); return -1; } /* only wait for incoming connections */ fdevent_add(control->fde, FDE_READ); D("jdwp control socket started (%d)", control->listen_socket); return 0; } static void jdwp_control_event(int fd, unsigned events, void* _control) { JdwpControl* control = (JdwpControl*)_control; CHECK_EQ(fd, control->listen_socket); if (events & FDE_READ) { int s = adb_socket_accept(control->listen_socket, nullptr, nullptr); if (s < 0) { if (errno == ECONNABORTED) { /* oops, the JDWP process died really quick */ D("oops, the JDWP process died really quick"); return; } else { /* the socket is probably closed ? */ D("weird accept() failed on jdwp control socket: %s", strerror(errno)); return; } } auto proc = std::make_unique<JdwpProcess>(s); if (!proc) { LOG(FATAL) << "failed to allocate JdwpProcess"; } _jdwp_list.emplace_back(std::move(proc)); } } /** "jdwp" local service implementation /** "jdwp" local service implementation ** this simply returns the list of known JDWP process pids ** this simply returns the list of known JDWP process pids **/ **/ Loading Loading @@ -526,7 +417,22 @@ asocket* create_jdwp_tracker_service_socket(void) { } } int init_jdwp(void) { int init_jdwp(void) { return jdwp_control_init(&_jdwp_control, JDWP_CONTROL_NAME, JDWP_CONTROL_NAME_LEN); std::thread([]() { adb_thread_setname("jdwp control"); adbconnection_listen([](int fd, pid_t pid) { LOG(INFO) << "jdwp connection from " << pid; fdevent_run_on_main_thread([fd, pid] { unique_fd ufd(fd); auto proc = std::make_unique<JdwpProcess>(std::move(ufd), pid); if (!proc) { LOG(FATAL) << "failed to allocate JdwpProcess"; } _jdwp_list.emplace_back(std::move(proc)); jdwp_process_list_updated(); }); }); }).detach(); return 0; } } #endif /* !ADB_HOST */ #endif /* !ADB_HOST */