Loading debuggerd/client/debuggerd_client.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -276,6 +276,13 @@ bool debuggerd_trigger_dump(pid_t tid, DebuggerdDumpType dump_type, unsigned int return false; } // WARNING: It's not possible to replace the below with a splice call. // Due to the way debuggerd does many small writes across the pipe, // this would cause splice to copy a page for each write. The second // pipe fills up based on the number of pages being copied, even // though there is not much data being transferred per page. When // the second pipe is full, everything stops since there is nothing // reading the second pipe to clear it. char buf[1024]; rc = TEMP_FAILURE_RETRY(read(pipe_read.get(), buf, sizeof(buf))); if (rc == 0) { Loading debuggerd/debuggerd.cpp +4 −24 Original line number Diff line number Diff line Loading @@ -41,22 +41,6 @@ static void usage(int exit_code) { _exit(exit_code); } static std::thread spawn_redirect_thread(unique_fd fd) { return std::thread([fd{ std::move(fd) }]() { while (true) { char buf[BUFSIZ]; ssize_t rc = TEMP_FAILURE_RETRY(read(fd.get(), buf, sizeof(buf))); if (rc <= 0) { return; } if (!android::base::WriteFully(STDOUT_FILENO, buf, rc)) { return; } } }); } int main(int argc, char* argv[]) { if (argc <= 1) usage(0); if (argc > 3) usage(1); Loading Loading @@ -107,14 +91,11 @@ int main(int argc, char* argv[]) { } } unique_fd piperead, pipewrite; if (!Pipe(&piperead, &pipewrite)) { err(1, "failed to create pipe"); unique_fd output_fd(fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 0)); if (output_fd.get() == -1) { err(1, "failed to fcntl dup stdout"); } std::thread redirect_thread = spawn_redirect_thread(std::move(piperead)); if (!debuggerd_trigger_dump(proc_info.pid, dump_type, 0, std::move(pipewrite))) { redirect_thread.join(); if (!debuggerd_trigger_dump(proc_info.pid, dump_type, 0, std::move(output_fd))) { if (pid == proc_info.pid) { errx(1, "failed to dump process %d", pid); } else { Loading @@ -122,6 +103,5 @@ int main(int argc, char* argv[]) { } } redirect_thread.join(); return 0; } Loading
debuggerd/client/debuggerd_client.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -276,6 +276,13 @@ bool debuggerd_trigger_dump(pid_t tid, DebuggerdDumpType dump_type, unsigned int return false; } // WARNING: It's not possible to replace the below with a splice call. // Due to the way debuggerd does many small writes across the pipe, // this would cause splice to copy a page for each write. The second // pipe fills up based on the number of pages being copied, even // though there is not much data being transferred per page. When // the second pipe is full, everything stops since there is nothing // reading the second pipe to clear it. char buf[1024]; rc = TEMP_FAILURE_RETRY(read(pipe_read.get(), buf, sizeof(buf))); if (rc == 0) { Loading
debuggerd/debuggerd.cpp +4 −24 Original line number Diff line number Diff line Loading @@ -41,22 +41,6 @@ static void usage(int exit_code) { _exit(exit_code); } static std::thread spawn_redirect_thread(unique_fd fd) { return std::thread([fd{ std::move(fd) }]() { while (true) { char buf[BUFSIZ]; ssize_t rc = TEMP_FAILURE_RETRY(read(fd.get(), buf, sizeof(buf))); if (rc <= 0) { return; } if (!android::base::WriteFully(STDOUT_FILENO, buf, rc)) { return; } } }); } int main(int argc, char* argv[]) { if (argc <= 1) usage(0); if (argc > 3) usage(1); Loading Loading @@ -107,14 +91,11 @@ int main(int argc, char* argv[]) { } } unique_fd piperead, pipewrite; if (!Pipe(&piperead, &pipewrite)) { err(1, "failed to create pipe"); unique_fd output_fd(fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 0)); if (output_fd.get() == -1) { err(1, "failed to fcntl dup stdout"); } std::thread redirect_thread = spawn_redirect_thread(std::move(piperead)); if (!debuggerd_trigger_dump(proc_info.pid, dump_type, 0, std::move(pipewrite))) { redirect_thread.join(); if (!debuggerd_trigger_dump(proc_info.pid, dump_type, 0, std::move(output_fd))) { if (pid == proc_info.pid) { errx(1, "failed to dump process %d", pid); } else { Loading @@ -122,6 +103,5 @@ int main(int argc, char* argv[]) { } } redirect_thread.join(); return 0; }