Give a clear error message if we can't start the server.

Bug: http://b/35218713
Test: adb kill-server ; export HOME=/ ; adb devices
Change-Id: I53cc30213be0eab84e42b09c7b501362d6e44b05
diff --git a/adb.cpp b/adb.cpp
index bfb1144..ff7b71f 100644
--- a/adb.cpp
+++ b/adb.cpp
@@ -49,6 +49,7 @@
 #include "adb_auth.h"
 #include "adb_io.h"
 #include "adb_listeners.h"
+#include "adb_unique_fd.h"
 #include "adb_utils.h"
 #include "sysdeps/chrono.h"
 #include "transport.h"
@@ -656,6 +657,26 @@
 
 #endif
 
+static void ReportServerStartupFailure(pid_t pid) {
+    fprintf(stderr, "ADB server didn't ACK\n");
+    fprintf(stderr, "Full server startup log: %s\n", GetLogFilePath().c_str());
+    fprintf(stderr, "Server had pid: %d\n", pid);
+
+    unique_fd fd(adb_open(GetLogFilePath().c_str(), O_RDONLY));
+    if (fd == -1) return;
+
+    // Let's not show more than 128KiB of log...
+    adb_lseek(fd, -128 * 1024, SEEK_END);
+    std::string content;
+    if (!android::base::ReadFdToString(fd, &content)) return;
+
+    std::string header = android::base::StringPrintf("--- adb starting (pid %d) ---", pid);
+    std::vector<std::string> lines = android::base::Split(content, "\n");
+    int i = lines.size() - 1;
+    while (i >= 0 && lines[i] != header) --i;
+    while (static_cast<size_t>(i) < lines.size()) fprintf(stderr, "%s\n", lines[i++].c_str());
+}
+
 int launch_server(const std::string& socket_spec) {
 #if defined(_WIN32)
     /* we need to start the server in the background                    */
@@ -835,7 +856,8 @@
                 memcmp(temp, expected, expected_length) == 0) {
                 got_ack = true;
             } else {
-                fprintf(stderr, "ADB server didn't ACK\n");
+                ReportServerStartupFailure(GetProcessId(process_handle.get()));
+                return -1;
             }
         } else {
             const DWORD err = GetLastError();
@@ -909,12 +931,9 @@
                            "--reply-fd", reply_fd, NULL);
         // this should not return
         fprintf(stderr, "adb: execl returned %d: %s\n", result, strerror(errno));
-    } else  {
+    } else {
         // parent side of the fork
-
-        char  temp[3];
-
-        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
+        char temp[3] = {};
         // wait for the "OK\n" message
         adb_close(fd[1]);
         int ret = adb_read(fd[0], temp, 3);
@@ -925,7 +944,7 @@
             return -1;
         }
         if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
-            fprintf(stderr, "ADB server didn't ACK\n" );
+            ReportServerStartupFailure(pid);
             return -1;
         }
     }
diff --git a/adb_utils.cpp b/adb_utils.cpp
index 6f2403d..bb26e70 100644
--- a/adb_utils.cpp
+++ b/adb_utils.cpp
@@ -278,3 +278,29 @@
     fprintf(stderr, "\n");
     return 1;
 }
+
+std::string GetLogFilePath() {
+#if defined(_WIN32)
+    const char log_name[] = "adb.log";
+    WCHAR temp_path[MAX_PATH];
+
+    // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
+    DWORD nchars = GetTempPathW(arraysize(temp_path), temp_path);
+    if (nchars >= arraysize(temp_path) || nchars == 0) {
+        // If string truncation or some other error.
+        fatal("cannot retrieve temporary file path: %s\n",
+              android::base::SystemErrorCodeToString(GetLastError()).c_str());
+    }
+
+    std::string temp_path_utf8;
+    if (!android::base::WideToUTF8(temp_path, &temp_path_utf8)) {
+        fatal_errno("cannot convert temporary file path from UTF-16 to UTF-8");
+    }
+
+    return temp_path_utf8 + log_name;
+#else
+    const char* tmp_dir = getenv("TMPDIR");
+    if (tmp_dir == nullptr) tmp_dir = "/tmp";
+    return android::base::StringPrintf("%s/adb.%u.log", tmp_dir, getuid());
+#endif
+}
diff --git a/adb_utils.h b/adb_utils.h
index 11c0ec9..f764a0e 100644
--- a/adb_utils.h
+++ b/adb_utils.h
@@ -89,4 +89,6 @@
     }
 };
 
+std::string GetLogFilePath();
+
 #endif
diff --git a/client/main.cpp b/client/main.cpp
index 62798cd..f0d0ce7 100644
--- a/client/main.cpp
+++ b/client/main.cpp
@@ -39,33 +39,7 @@
 #include "sysdeps/chrono.h"
 #include "transport.h"
 
-static std::string GetLogFilePath() {
-#if defined(_WIN32)
-    const char log_name[] = "adb.log";
-    WCHAR temp_path[MAX_PATH];
-
-    // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
-    DWORD nchars = GetTempPathW(arraysize(temp_path), temp_path);
-    if (nchars >= arraysize(temp_path) || nchars == 0) {
-        // If string truncation or some other error.
-        fatal("cannot retrieve temporary file path: %s\n",
-              android::base::SystemErrorCodeToString(GetLastError()).c_str());
-    }
-
-    std::string temp_path_utf8;
-    if (!android::base::WideToUTF8(temp_path, &temp_path_utf8)) {
-        fatal_errno("cannot convert temporary file path from UTF-16 to UTF-8");
-    }
-
-    return temp_path_utf8 + log_name;
-#else
-    const char* tmp_dir = getenv("TMPDIR");
-    if (tmp_dir == nullptr) tmp_dir = "/tmp";
-    return android::base::StringPrintf("%s/adb.%u.log", tmp_dir, getuid());
-#endif
-}
-
-static void setup_daemon_logging(void) {
+static void setup_daemon_logging() {
     const std::string log_file_path(GetLogFilePath());
     int fd = unix_open(log_file_path.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0640);
     if (fd == -1) {