debuggerd_client: increase pipe buffer size to max.

If a process tries to dump itself (e.g. system_server during ANRs),
crash_dump will block trying to write to its pipe if it's not
sufficiently large. Increase the pipe size to the max, and add a test
to make sure that it's always at least 1MB (the default value).

Bug: http://b/38427757
Test: debuggerd_test
Merged-In: Iddb0cb1e5ce9e687efa9e94c2748a1edfe09f119
Change-Id: Iddb0cb1e5ce9e687efa9e94c2748a1edfe09f119
(cherry picked from commit 5675f3c321b7c6a9bbb2a7aacf18a01126f2f2cb)
diff --git a/debuggerd/client/debuggerd_client.cpp b/debuggerd/client/debuggerd_client.cpp
index 3b84853..d1df088 100644
--- a/debuggerd/client/debuggerd_client.cpp
+++ b/debuggerd/client/debuggerd_client.cpp
@@ -28,7 +28,9 @@
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/parseint.h>
 #include <android-base/stringprintf.h>
+#include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <cutils/sockets.h>
 #include <debuggerd/handler.h>
@@ -114,6 +116,20 @@
     return false;
   }
 
+  std::string pipe_size_str;
+  int pipe_buffer_size = 1024 * 1024;
+  if (android::base::ReadFileToString("/proc/sys/fs/pipe-max-size", &pipe_size_str)) {
+    pipe_size_str = android::base::Trim(pipe_size_str);
+
+    if (!android::base::ParseInt(pipe_size_str.c_str(), &pipe_buffer_size, 0)) {
+      LOG(FATAL) << "failed to parse pipe max size '" << pipe_size_str << "'";
+    }
+  }
+
+  if (fcntl(pipe_read.get(), F_SETPIPE_SZ, pipe_buffer_size) != pipe_buffer_size) {
+    PLOG(ERROR) << "failed to set pipe buffer size";
+  }
+
   if (send_fd(set_timeout(sockfd), &req, sizeof(req), std::move(pipe_write)) != sizeof(req)) {
     PLOG(ERROR) << "libdebuggerd_client: failed to send output fd to tombstoned";
     return false;
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 0b4bbfb..fa0626b 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -117,6 +117,8 @@
     FAIL() << "failed to set pipe size: " << strerror(errno);
   }
 
+  ASSERT_GE(pipe_buffer_size, 1024 * 1024);
+
   if (send_fd(intercept_fd->get(), &req, sizeof(req), std::move(output_pipe_write)) != sizeof(req)) {
     FAIL() << "failed to send output fd to tombstoned: " << strerror(errno);
   }