Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56abaa09 authored by Frederick Mayle's avatar Frederick Mayle Committed by Christopher Ferris
Browse files

debuggerd: simplify output handling

Just noticed some opportunities while skimming.

Test: adb shell debuggerd $(adb shell pidof com.android.systemui)
Test: All unit tests pass (both 32 bit and 64 bit).
Test: Ran unit tests in a loop hundreds of times.
Change-Id: I428d0cf599ed603a21944b084b95594db893cbd5
parent 6e80656b
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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) {
+4 −24
Original line number Diff line number Diff line
@@ -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);
@@ -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 {
@@ -122,6 +103,5 @@ int main(int argc, char* argv[]) {
    }
  }

  redirect_thread.join();
  return 0;
}