From 6eadee860798bf4e0be0293450017fbc95ff41c8 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 15 Jun 2017 08:35:24 -0700 Subject: [PATCH] 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 --- adb/adb.cpp | 33 ++++++++++++++++++++++++++------- adb/adb_utils.cpp | 26 ++++++++++++++++++++++++++ adb/adb_utils.h | 2 ++ adb/client/main.cpp | 28 +--------------------------- 4 files changed, 55 insertions(+), 34 deletions(-) diff --git a/adb/adb.cpp b/adb/adb.cpp index bfb1144d4..ff7b71f81 100644 --- a/adb/adb.cpp +++ b/adb/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 @@ static unsigned __stdcall _redirect_stderr_thread(HANDLE h) { #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 lines = android::base::Split(content, "\n"); + int i = lines.size() - 1; + while (i >= 0 && lines[i] != header) --i; + while (static_cast(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 @@ int launch_server(const std::string& socket_spec) { 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 @@ int launch_server(const std::string& socket_spec) { "--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 @@ int launch_server(const std::string& socket_spec) { 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/adb_utils.cpp b/adb/adb_utils.cpp index 6f2403d03..bb26e7080 100644 --- a/adb/adb_utils.cpp +++ b/adb/adb_utils.cpp @@ -278,3 +278,29 @@ int syntax_error(const char* fmt, ...) { 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/adb_utils.h b/adb/adb_utils.h index 11c0ec9cc..f764a0eea 100644 --- a/adb/adb_utils.h +++ b/adb/adb_utils.h @@ -89,4 +89,6 @@ class BlockingQueue { } }; +std::string GetLogFilePath(); + #endif diff --git a/adb/client/main.cpp b/adb/client/main.cpp index 62798cde7..f0d0ce799 100644 --- a/adb/client/main.cpp +++ b/adb/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) {