Loading adb/Android.bp +15 −1 Original line number Diff line number Diff line Loading @@ -314,6 +314,7 @@ cc_binary_host { "libadb_protos", "libadb_tls_connection", "libandroidfw", "libapp_processes_protos_full", "libbase", "libcutils", "libcrypto_utils", Loading @@ -323,7 +324,7 @@ cc_binary_host { "liblog", "liblz4", "libmdnssd", "libprotobuf-cpp-lite", "libprotobuf-cpp-full", "libssl", "libusb", "libutils", Loading Loading @@ -387,6 +388,7 @@ cc_library_static { static_libs: [ "libadbconnection_server", "libapp_processes_protos_lite", "libdiagnose_usb", ], Loading @@ -403,6 +405,12 @@ cc_library_static { "liblog", ], proto: { type: "lite", static: true, export_proto_headers: true, }, target: { android: { whole_static_libs: [ Loading Loading @@ -450,7 +458,9 @@ cc_library_static { static_libs: [ "libadbconnection_server", "libadbd_core", "libapp_processes_protos_lite", "libdiagnose_usb", "libprotobuf-cpp-lite", ], shared_libs: [ Loading Loading @@ -507,6 +517,8 @@ cc_library { whole_static_libs: [ "libadbconnection_server", "libadbd_core", "libapp_processes_protos_lite", "libprotobuf-cpp-lite", ], shared_libs: [ Loading Loading @@ -569,6 +581,7 @@ cc_binary { "libadbconnection_server", "libadbd", "libadbd_services", "libapp_processes_protos_lite", "libasyncio", "libbase", "libcap", Loading @@ -578,6 +591,7 @@ cc_binary { "liblog", "libmdnssd", "libminijail", "libprotobuf-cpp-lite", "libselinux", "libssl", ], Loading adb/adb.h +1 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,7 @@ unique_fd execute_abb_command(std::string_view command); int init_jdwp(void); asocket* create_jdwp_service_socket(); asocket* create_jdwp_tracker_service_socket(); asocket* create_app_tracker_service_socket(); unique_fd create_jdwp_connection_fd(int jdwp_pid); #endif Loading adb/client/commandline.cpp +49 −2 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ #include <unistd.h> #endif #include <google/protobuf/text_format.h> #include "adb.h" #include "adb_auth.h" #include "adb_client.h" Loading @@ -57,6 +59,7 @@ #include "adb_io.h" #include "adb_unique_fd.h" #include "adb_utils.h" #include "app_processes.pb.h" #include "bugreport.h" #include "client/file_sync_client.h" #include "commandline.h" Loading Loading @@ -1354,17 +1357,49 @@ static void parse_push_pull_args(const char** arg, int narg, std::vector<const c } } static int adb_connect_command(const std::string& command, TransportId* transport = nullptr) { static int adb_connect_command(const std::string& command, TransportId* transport, StandardStreamsCallbackInterface* callback) { std::string error; unique_fd fd(adb_connect(transport, command, &error)); if (fd < 0) { fprintf(stderr, "error: %s\n", error.c_str()); return 1; } read_and_dump(fd); read_and_dump(fd, false, callback); return 0; } static int adb_connect_command(const std::string& command, TransportId* transport = nullptr) { return adb_connect_command(command, transport, &DEFAULT_STANDARD_STREAMS_CALLBACK); } // A class that prints out human readable form of the protobuf message for "track-app" service // (received in binary format). class TrackAppStreamsCallback : public DefaultStandardStreamsCallback { public: TrackAppStreamsCallback() : DefaultStandardStreamsCallback(nullptr, nullptr) {} // Assume the buffer contains at least 4 bytes of valid data. void OnStdout(const char* buffer, int length) override { if (length < 4) return; // Unexpected length received. Do nothing. adb::proto::AppProcesses binary_proto; // The first 4 bytes are the length of remaining content in hexadecimal format. binary_proto.ParseFromString(std::string(buffer + 4, length - 4)); char summary[24]; // The following string includes digits and 16 fixed characters. int written = snprintf(summary, sizeof(summary), "Process count: %d\n", binary_proto.process_size()); OnStream(nullptr, stdout, summary, written); std::string string_proto; google::protobuf::TextFormat::PrintToString(binary_proto, &string_proto); OnStream(nullptr, stdout, string_proto.data(), string_proto.length()); } private: DISALLOW_COPY_AND_ASSIGN(TrackAppStreamsCallback); }; static int adb_connect_command_bidirectional(const std::string& command) { std::string error; unique_fd fd(adb_connect(command, &error)); Loading Loading @@ -1925,6 +1960,18 @@ int adb_commandline(int argc, const char** argv) { return adb_connect_command("jdwp"); } else if (!strcmp(argv[0], "track-jdwp")) { return adb_connect_command("track-jdwp"); } else if (!strcmp(argv[0], "track-app")) { FeatureSet features; std::string error; if (!adb_get_feature_set(&features, &error)) { fprintf(stderr, "error: %s\n", error.c_str()); return 1; } if (!CanUseFeature(features, kFeatureTrackApp)) { error_exit("track-app is not supported by the device"); } TrackAppStreamsCallback callback; return adb_connect_command("track-app", nullptr, &callback); } else if (!strcmp(argv[0], "track-devices")) { if (argc > 2 || (argc == 2 && strcmp(argv[1], "-l"))) { error_exit("usage: adb track-devices [-l]"); Loading adb/daemon/jdwp_service.cpp +99 −25 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include "sysdeps.h" #include <errno.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <string.h> Loading @@ -33,6 +34,7 @@ #include <thread> #include <vector> #include <adbconnection/process_info.h> #include <adbconnection/server.h> #include <android-base/cmsg.h> #include <android-base/unique_fd.h> Loading @@ -41,6 +43,7 @@ #include "adb_io.h" #include "adb_unique_fd.h" #include "adb_utils.h" #include "app_processes.pb.h" using android::base::borrowed_fd; using android::base::unique_fd; Loading Loading @@ -132,18 +135,24 @@ using android::base::unique_fd; ** for each JDWP process, we record its pid and its connected socket **/ enum class TrackerKind { kJdwp, kApp, }; static void jdwp_process_event(int socket, unsigned events, void* _proc); static void jdwp_process_list_updated(void); static void app_process_list_updated(void); struct JdwpProcess; static auto& _jdwp_list = *new std::list<std::unique_ptr<JdwpProcess>>(); struct JdwpProcess { JdwpProcess(unique_fd socket, pid_t pid) { CHECK(pid != 0); JdwpProcess(unique_fd socket, ProcessInfo process) { CHECK(process.pid != 0); this->socket = socket; this->pid = pid; this->process = process; this->fde = fdevent_create(socket.release(), jdwp_process_event, this); if (!this->fde) { Loading Loading @@ -171,17 +180,19 @@ struct JdwpProcess { } borrowed_fd socket = -1; int32_t pid = -1; ProcessInfo process; fdevent* fde = nullptr; std::vector<unique_fd> out_fds; }; // Populate the list of processes for "track-jdwp" service. static size_t jdwp_process_list(char* buffer, size_t bufferlen) { std::string temp; for (auto& proc : _jdwp_list) { std::string next = std::to_string(proc->pid) + "\n"; if (!proc->process.debuggable) continue; std::string next = std::to_string(proc->process.pid) + "\n"; if (temp.length() + next.length() > bufferlen) { D("truncating JDWP process list (max len = %zu)", bufferlen); break; Loading @@ -193,7 +204,44 @@ static size_t jdwp_process_list(char* buffer, size_t bufferlen) { return temp.length(); } static size_t jdwp_process_list_msg(char* buffer, size_t bufferlen) { // Populate the list of processes for "track-app" service. // The list is a protobuf message in the binary format for efficiency. static size_t app_process_list(char* buffer, size_t bufferlen) { adb::proto::AppProcesses output; // result that's guaranteed to fit in the given buffer adb::proto::AppProcesses temp; // temporary result that may be longer than the given buffer std::string serialized_message; for (auto& proc : _jdwp_list) { if (!proc->process.debuggable && !proc->process.profileable) continue; auto* entry = temp.add_process(); entry->set_pid(proc->process.pid); entry->set_debuggable(proc->process.debuggable); entry->set_profileable(proc->process.profileable); entry->set_architecture(proc->process.arch_name, proc->process.arch_name_length); temp.SerializeToString(&serialized_message); if (serialized_message.size() > bufferlen) { D("truncating app process list (max len = %zu)", bufferlen); break; } output = temp; } output.SerializeToString(&serialized_message); memcpy(buffer, serialized_message.data(), serialized_message.length()); return serialized_message.length(); } // Populate the list of processes for either "track-jdwp" or "track-app" services, // depending on the given kind. static size_t process_list(TrackerKind kind, char* buffer, size_t bufferlen) { switch (kind) { case TrackerKind::kJdwp: return jdwp_process_list(buffer, bufferlen); case TrackerKind::kApp: return app_process_list(buffer, bufferlen); } } static size_t process_list_msg(TrackerKind kind, char* buffer, size_t bufferlen) { // Message is length-prefixed with 4 hex digits in ASCII. static constexpr size_t header_len = 4; if (bufferlen < header_len) { Loading @@ -201,7 +249,7 @@ static size_t jdwp_process_list_msg(char* buffer, size_t bufferlen) { } char head[header_len + 1]; size_t len = jdwp_process_list(buffer + header_len, bufferlen - header_len); size_t len = process_list(kind, buffer + header_len, bufferlen - header_len); snprintf(head, sizeof head, "%04zx", len); memcpy(buffer, head, header_len); return len + header_len; Loading @@ -213,7 +261,7 @@ static void jdwp_process_event(int socket, unsigned events, void* _proc) { if (events & FDE_READ) { // 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 %" PRId64, proc->process.pid); goto CloseProcess; } Loading @@ -223,11 +271,12 @@ static void jdwp_process_event(int socket, unsigned events, void* _proc) { int fd = proc->out_fds.back().get(); if (android::base::SendFileDescriptors(socket, "", 1, fd) != 1) { D("sending new file descriptor to JDWP %d failed: %s", proc->pid, strerror(errno)); D("sending new file descriptor to JDWP %" PRId64 " failed: %s", proc->process.pid, strerror(errno)); goto CloseProcess; } D("sent file descriptor %d to JDWP process %d", fd, proc->pid); D("sent file descriptor %d to JDWP process %" PRId64, fd, proc->process.pid); proc->out_fds.pop_back(); if (proc->out_fds.empty()) { Loading @@ -238,15 +287,20 @@ static void jdwp_process_event(int socket, unsigned events, void* _proc) { return; CloseProcess: bool debuggable = proc->process.debuggable; bool profileable = proc->process.profileable; proc->RemoveFromList(); jdwp_process_list_updated(); if (debuggable) jdwp_process_list_updated(); if (debuggable || profileable) app_process_list_updated(); } unique_fd create_jdwp_connection_fd(int pid) { D("looking for pid %d in JDWP process list", pid); for (auto& proc : _jdwp_list) { if (proc->pid == pid) { // Don't allow JDWP connection to a non-debuggable process. if (!proc->process.debuggable) continue; if (proc->process.pid == static_cast<uint64_t>(pid)) { int fds[2]; if (adb_socketpair(fds) < 0) { Loading Loading @@ -338,18 +392,22 @@ asocket* create_jdwp_service_socket(void) { **/ struct JdwpTracker : public asocket { TrackerKind kind; bool need_initial; explicit JdwpTracker(TrackerKind k, bool initial) : kind(k), need_initial(initial) {} }; static auto& _jdwp_trackers = *new std::vector<std::unique_ptr<JdwpTracker>>(); static void jdwp_process_list_updated(void) { static void process_list_updated(TrackerKind kind) { std::string data; data.resize(1024); data.resize(jdwp_process_list_msg(&data[0], data.size())); const int kMaxLength = kind == TrackerKind::kJdwp ? 1024 : 2048; data.resize(kMaxLength); data.resize(process_list_msg(kind, &data[0], data.size())); for (auto& t : _jdwp_trackers) { if (t->peer) { if (t->kind == kind && t->peer) { // The tracker might not have been connected yet. apacket::payload_type payload(data.begin(), data.end()); t->peer->enqueue(t->peer, std::move(payload)); Loading @@ -357,6 +415,14 @@ static void jdwp_process_list_updated(void) { } } static void jdwp_process_list_updated(void) { process_list_updated(TrackerKind::kJdwp); } static void app_process_list_updated(void) { process_list_updated(TrackerKind::kApp); } static void jdwp_tracker_close(asocket* s) { D("LS(%d): destroying jdwp tracker service", s->id); Loading @@ -380,7 +446,7 @@ static void jdwp_tracker_ready(asocket* s) { if (t->need_initial) { apacket::payload_type data; data.resize(s->get_max_payload()); data.resize(jdwp_process_list_msg(&data[0], data.size())); data.resize(process_list_msg(t->kind, &data[0], data.size())); t->need_initial = false; s->peer->enqueue(s->peer, std::move(data)); } Loading @@ -393,8 +459,8 @@ static int jdwp_tracker_enqueue(asocket* s, apacket::payload_type) { return -1; } asocket* create_jdwp_tracker_service_socket(void) { auto t = std::make_unique<JdwpTracker>(); asocket* create_process_tracker_service_socket(TrackerKind kind) { auto t = std::make_unique<JdwpTracker>(kind, true); if (!t) { LOG(FATAL) << "failed to allocate JdwpTracker"; } Loading @@ -407,7 +473,6 @@ asocket* create_jdwp_tracker_service_socket(void) { t->ready = jdwp_tracker_ready; t->enqueue = jdwp_tracker_enqueue; t->close = jdwp_tracker_close; t->need_initial = true; asocket* result = t.get(); Loading @@ -416,19 +481,28 @@ asocket* create_jdwp_tracker_service_socket(void) { return result; } asocket* create_jdwp_tracker_service_socket() { return create_process_tracker_service_socket(TrackerKind::kJdwp); } asocket* create_app_tracker_service_socket() { return create_process_tracker_service_socket(TrackerKind::kApp); } int init_jdwp(void) { 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] { adbconnection_listen([](int fd, ProcessInfo process) { LOG(INFO) << "jdwp connection from " << process.pid; fdevent_run_on_main_thread([fd, process] { unique_fd ufd(fd); auto proc = std::make_unique<JdwpProcess>(std::move(ufd), pid); auto proc = std::make_unique<JdwpProcess>(std::move(ufd), process); if (!proc) { LOG(FATAL) << "failed to allocate JdwpProcess"; } _jdwp_list.emplace_back(std::move(proc)); jdwp_process_list_updated(); if (process.debuggable) jdwp_process_list_updated(); if (process.debuggable || process.profileable) app_process_list_updated(); }); }); }).detach(); Loading adb/daemon/services.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -241,6 +241,8 @@ asocket* daemon_service_to_socket(std::string_view name) { return create_jdwp_service_socket(); } else if (name == "track-jdwp") { return create_jdwp_tracker_service_socket(); } else if (name == "track-app") { return create_app_tracker_service_socket(); } else if (android::base::ConsumePrefix(&name, "sink:")) { uint64_t byte_count = 0; if (!ParseUint(&byte_count, name)) { Loading Loading
adb/Android.bp +15 −1 Original line number Diff line number Diff line Loading @@ -314,6 +314,7 @@ cc_binary_host { "libadb_protos", "libadb_tls_connection", "libandroidfw", "libapp_processes_protos_full", "libbase", "libcutils", "libcrypto_utils", Loading @@ -323,7 +324,7 @@ cc_binary_host { "liblog", "liblz4", "libmdnssd", "libprotobuf-cpp-lite", "libprotobuf-cpp-full", "libssl", "libusb", "libutils", Loading Loading @@ -387,6 +388,7 @@ cc_library_static { static_libs: [ "libadbconnection_server", "libapp_processes_protos_lite", "libdiagnose_usb", ], Loading @@ -403,6 +405,12 @@ cc_library_static { "liblog", ], proto: { type: "lite", static: true, export_proto_headers: true, }, target: { android: { whole_static_libs: [ Loading Loading @@ -450,7 +458,9 @@ cc_library_static { static_libs: [ "libadbconnection_server", "libadbd_core", "libapp_processes_protos_lite", "libdiagnose_usb", "libprotobuf-cpp-lite", ], shared_libs: [ Loading Loading @@ -507,6 +517,8 @@ cc_library { whole_static_libs: [ "libadbconnection_server", "libadbd_core", "libapp_processes_protos_lite", "libprotobuf-cpp-lite", ], shared_libs: [ Loading Loading @@ -569,6 +581,7 @@ cc_binary { "libadbconnection_server", "libadbd", "libadbd_services", "libapp_processes_protos_lite", "libasyncio", "libbase", "libcap", Loading @@ -578,6 +591,7 @@ cc_binary { "liblog", "libmdnssd", "libminijail", "libprotobuf-cpp-lite", "libselinux", "libssl", ], Loading
adb/adb.h +1 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,7 @@ unique_fd execute_abb_command(std::string_view command); int init_jdwp(void); asocket* create_jdwp_service_socket(); asocket* create_jdwp_tracker_service_socket(); asocket* create_app_tracker_service_socket(); unique_fd create_jdwp_connection_fd(int jdwp_pid); #endif Loading
adb/client/commandline.cpp +49 −2 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ #include <unistd.h> #endif #include <google/protobuf/text_format.h> #include "adb.h" #include "adb_auth.h" #include "adb_client.h" Loading @@ -57,6 +59,7 @@ #include "adb_io.h" #include "adb_unique_fd.h" #include "adb_utils.h" #include "app_processes.pb.h" #include "bugreport.h" #include "client/file_sync_client.h" #include "commandline.h" Loading Loading @@ -1354,17 +1357,49 @@ static void parse_push_pull_args(const char** arg, int narg, std::vector<const c } } static int adb_connect_command(const std::string& command, TransportId* transport = nullptr) { static int adb_connect_command(const std::string& command, TransportId* transport, StandardStreamsCallbackInterface* callback) { std::string error; unique_fd fd(adb_connect(transport, command, &error)); if (fd < 0) { fprintf(stderr, "error: %s\n", error.c_str()); return 1; } read_and_dump(fd); read_and_dump(fd, false, callback); return 0; } static int adb_connect_command(const std::string& command, TransportId* transport = nullptr) { return adb_connect_command(command, transport, &DEFAULT_STANDARD_STREAMS_CALLBACK); } // A class that prints out human readable form of the protobuf message for "track-app" service // (received in binary format). class TrackAppStreamsCallback : public DefaultStandardStreamsCallback { public: TrackAppStreamsCallback() : DefaultStandardStreamsCallback(nullptr, nullptr) {} // Assume the buffer contains at least 4 bytes of valid data. void OnStdout(const char* buffer, int length) override { if (length < 4) return; // Unexpected length received. Do nothing. adb::proto::AppProcesses binary_proto; // The first 4 bytes are the length of remaining content in hexadecimal format. binary_proto.ParseFromString(std::string(buffer + 4, length - 4)); char summary[24]; // The following string includes digits and 16 fixed characters. int written = snprintf(summary, sizeof(summary), "Process count: %d\n", binary_proto.process_size()); OnStream(nullptr, stdout, summary, written); std::string string_proto; google::protobuf::TextFormat::PrintToString(binary_proto, &string_proto); OnStream(nullptr, stdout, string_proto.data(), string_proto.length()); } private: DISALLOW_COPY_AND_ASSIGN(TrackAppStreamsCallback); }; static int adb_connect_command_bidirectional(const std::string& command) { std::string error; unique_fd fd(adb_connect(command, &error)); Loading Loading @@ -1925,6 +1960,18 @@ int adb_commandline(int argc, const char** argv) { return adb_connect_command("jdwp"); } else if (!strcmp(argv[0], "track-jdwp")) { return adb_connect_command("track-jdwp"); } else if (!strcmp(argv[0], "track-app")) { FeatureSet features; std::string error; if (!adb_get_feature_set(&features, &error)) { fprintf(stderr, "error: %s\n", error.c_str()); return 1; } if (!CanUseFeature(features, kFeatureTrackApp)) { error_exit("track-app is not supported by the device"); } TrackAppStreamsCallback callback; return adb_connect_command("track-app", nullptr, &callback); } else if (!strcmp(argv[0], "track-devices")) { if (argc > 2 || (argc == 2 && strcmp(argv[1], "-l"))) { error_exit("usage: adb track-devices [-l]"); Loading
adb/daemon/jdwp_service.cpp +99 −25 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include "sysdeps.h" #include <errno.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <string.h> Loading @@ -33,6 +34,7 @@ #include <thread> #include <vector> #include <adbconnection/process_info.h> #include <adbconnection/server.h> #include <android-base/cmsg.h> #include <android-base/unique_fd.h> Loading @@ -41,6 +43,7 @@ #include "adb_io.h" #include "adb_unique_fd.h" #include "adb_utils.h" #include "app_processes.pb.h" using android::base::borrowed_fd; using android::base::unique_fd; Loading Loading @@ -132,18 +135,24 @@ using android::base::unique_fd; ** for each JDWP process, we record its pid and its connected socket **/ enum class TrackerKind { kJdwp, kApp, }; static void jdwp_process_event(int socket, unsigned events, void* _proc); static void jdwp_process_list_updated(void); static void app_process_list_updated(void); struct JdwpProcess; static auto& _jdwp_list = *new std::list<std::unique_ptr<JdwpProcess>>(); struct JdwpProcess { JdwpProcess(unique_fd socket, pid_t pid) { CHECK(pid != 0); JdwpProcess(unique_fd socket, ProcessInfo process) { CHECK(process.pid != 0); this->socket = socket; this->pid = pid; this->process = process; this->fde = fdevent_create(socket.release(), jdwp_process_event, this); if (!this->fde) { Loading Loading @@ -171,17 +180,19 @@ struct JdwpProcess { } borrowed_fd socket = -1; int32_t pid = -1; ProcessInfo process; fdevent* fde = nullptr; std::vector<unique_fd> out_fds; }; // Populate the list of processes for "track-jdwp" service. static size_t jdwp_process_list(char* buffer, size_t bufferlen) { std::string temp; for (auto& proc : _jdwp_list) { std::string next = std::to_string(proc->pid) + "\n"; if (!proc->process.debuggable) continue; std::string next = std::to_string(proc->process.pid) + "\n"; if (temp.length() + next.length() > bufferlen) { D("truncating JDWP process list (max len = %zu)", bufferlen); break; Loading @@ -193,7 +204,44 @@ static size_t jdwp_process_list(char* buffer, size_t bufferlen) { return temp.length(); } static size_t jdwp_process_list_msg(char* buffer, size_t bufferlen) { // Populate the list of processes for "track-app" service. // The list is a protobuf message in the binary format for efficiency. static size_t app_process_list(char* buffer, size_t bufferlen) { adb::proto::AppProcesses output; // result that's guaranteed to fit in the given buffer adb::proto::AppProcesses temp; // temporary result that may be longer than the given buffer std::string serialized_message; for (auto& proc : _jdwp_list) { if (!proc->process.debuggable && !proc->process.profileable) continue; auto* entry = temp.add_process(); entry->set_pid(proc->process.pid); entry->set_debuggable(proc->process.debuggable); entry->set_profileable(proc->process.profileable); entry->set_architecture(proc->process.arch_name, proc->process.arch_name_length); temp.SerializeToString(&serialized_message); if (serialized_message.size() > bufferlen) { D("truncating app process list (max len = %zu)", bufferlen); break; } output = temp; } output.SerializeToString(&serialized_message); memcpy(buffer, serialized_message.data(), serialized_message.length()); return serialized_message.length(); } // Populate the list of processes for either "track-jdwp" or "track-app" services, // depending on the given kind. static size_t process_list(TrackerKind kind, char* buffer, size_t bufferlen) { switch (kind) { case TrackerKind::kJdwp: return jdwp_process_list(buffer, bufferlen); case TrackerKind::kApp: return app_process_list(buffer, bufferlen); } } static size_t process_list_msg(TrackerKind kind, char* buffer, size_t bufferlen) { // Message is length-prefixed with 4 hex digits in ASCII. static constexpr size_t header_len = 4; if (bufferlen < header_len) { Loading @@ -201,7 +249,7 @@ static size_t jdwp_process_list_msg(char* buffer, size_t bufferlen) { } char head[header_len + 1]; size_t len = jdwp_process_list(buffer + header_len, bufferlen - header_len); size_t len = process_list(kind, buffer + header_len, bufferlen - header_len); snprintf(head, sizeof head, "%04zx", len); memcpy(buffer, head, header_len); return len + header_len; Loading @@ -213,7 +261,7 @@ static void jdwp_process_event(int socket, unsigned events, void* _proc) { if (events & FDE_READ) { // 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 %" PRId64, proc->process.pid); goto CloseProcess; } Loading @@ -223,11 +271,12 @@ static void jdwp_process_event(int socket, unsigned events, void* _proc) { int fd = proc->out_fds.back().get(); if (android::base::SendFileDescriptors(socket, "", 1, fd) != 1) { D("sending new file descriptor to JDWP %d failed: %s", proc->pid, strerror(errno)); D("sending new file descriptor to JDWP %" PRId64 " failed: %s", proc->process.pid, strerror(errno)); goto CloseProcess; } D("sent file descriptor %d to JDWP process %d", fd, proc->pid); D("sent file descriptor %d to JDWP process %" PRId64, fd, proc->process.pid); proc->out_fds.pop_back(); if (proc->out_fds.empty()) { Loading @@ -238,15 +287,20 @@ static void jdwp_process_event(int socket, unsigned events, void* _proc) { return; CloseProcess: bool debuggable = proc->process.debuggable; bool profileable = proc->process.profileable; proc->RemoveFromList(); jdwp_process_list_updated(); if (debuggable) jdwp_process_list_updated(); if (debuggable || profileable) app_process_list_updated(); } unique_fd create_jdwp_connection_fd(int pid) { D("looking for pid %d in JDWP process list", pid); for (auto& proc : _jdwp_list) { if (proc->pid == pid) { // Don't allow JDWP connection to a non-debuggable process. if (!proc->process.debuggable) continue; if (proc->process.pid == static_cast<uint64_t>(pid)) { int fds[2]; if (adb_socketpair(fds) < 0) { Loading Loading @@ -338,18 +392,22 @@ asocket* create_jdwp_service_socket(void) { **/ struct JdwpTracker : public asocket { TrackerKind kind; bool need_initial; explicit JdwpTracker(TrackerKind k, bool initial) : kind(k), need_initial(initial) {} }; static auto& _jdwp_trackers = *new std::vector<std::unique_ptr<JdwpTracker>>(); static void jdwp_process_list_updated(void) { static void process_list_updated(TrackerKind kind) { std::string data; data.resize(1024); data.resize(jdwp_process_list_msg(&data[0], data.size())); const int kMaxLength = kind == TrackerKind::kJdwp ? 1024 : 2048; data.resize(kMaxLength); data.resize(process_list_msg(kind, &data[0], data.size())); for (auto& t : _jdwp_trackers) { if (t->peer) { if (t->kind == kind && t->peer) { // The tracker might not have been connected yet. apacket::payload_type payload(data.begin(), data.end()); t->peer->enqueue(t->peer, std::move(payload)); Loading @@ -357,6 +415,14 @@ static void jdwp_process_list_updated(void) { } } static void jdwp_process_list_updated(void) { process_list_updated(TrackerKind::kJdwp); } static void app_process_list_updated(void) { process_list_updated(TrackerKind::kApp); } static void jdwp_tracker_close(asocket* s) { D("LS(%d): destroying jdwp tracker service", s->id); Loading @@ -380,7 +446,7 @@ static void jdwp_tracker_ready(asocket* s) { if (t->need_initial) { apacket::payload_type data; data.resize(s->get_max_payload()); data.resize(jdwp_process_list_msg(&data[0], data.size())); data.resize(process_list_msg(t->kind, &data[0], data.size())); t->need_initial = false; s->peer->enqueue(s->peer, std::move(data)); } Loading @@ -393,8 +459,8 @@ static int jdwp_tracker_enqueue(asocket* s, apacket::payload_type) { return -1; } asocket* create_jdwp_tracker_service_socket(void) { auto t = std::make_unique<JdwpTracker>(); asocket* create_process_tracker_service_socket(TrackerKind kind) { auto t = std::make_unique<JdwpTracker>(kind, true); if (!t) { LOG(FATAL) << "failed to allocate JdwpTracker"; } Loading @@ -407,7 +473,6 @@ asocket* create_jdwp_tracker_service_socket(void) { t->ready = jdwp_tracker_ready; t->enqueue = jdwp_tracker_enqueue; t->close = jdwp_tracker_close; t->need_initial = true; asocket* result = t.get(); Loading @@ -416,19 +481,28 @@ asocket* create_jdwp_tracker_service_socket(void) { return result; } asocket* create_jdwp_tracker_service_socket() { return create_process_tracker_service_socket(TrackerKind::kJdwp); } asocket* create_app_tracker_service_socket() { return create_process_tracker_service_socket(TrackerKind::kApp); } int init_jdwp(void) { 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] { adbconnection_listen([](int fd, ProcessInfo process) { LOG(INFO) << "jdwp connection from " << process.pid; fdevent_run_on_main_thread([fd, process] { unique_fd ufd(fd); auto proc = std::make_unique<JdwpProcess>(std::move(ufd), pid); auto proc = std::make_unique<JdwpProcess>(std::move(ufd), process); if (!proc) { LOG(FATAL) << "failed to allocate JdwpProcess"; } _jdwp_list.emplace_back(std::move(proc)); jdwp_process_list_updated(); if (process.debuggable) jdwp_process_list_updated(); if (process.debuggable || process.profileable) app_process_list_updated(); }); }); }).detach(); Loading
adb/daemon/services.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -241,6 +241,8 @@ asocket* daemon_service_to_socket(std::string_view name) { return create_jdwp_service_socket(); } else if (name == "track-jdwp") { return create_jdwp_tracker_service_socket(); } else if (name == "track-app") { return create_app_tracker_service_socket(); } else if (android::base::ConsumePrefix(&name, "sink:")) { uint64_t byte_count = 0; if (!ParseUint(&byte_count, name)) { Loading