diff options
author | Mark Salyzyn <salyzyn@google.com> | 2013-11-22 10:53:34 -0800 |
---|---|---|
committer | Mark Salyzyn <salyzyn@google.com> | 2014-01-27 15:11:10 -0800 |
commit | 22b5cef1277a5e1d5deef7420281eafade2e2614 (patch) | |
tree | 4b57d3ef406794d6a654c274c4a50c9a02402447 /debuggerd | |
parent | 4295841ebe68a2ebf50ed7adf0a603c523d5af52 (diff) | |
download | system_core-22b5cef1277a5e1d5deef7420281eafade2e2614.zip system_core-22b5cef1277a5e1d5deef7420281eafade2e2614.tar.gz system_core-22b5cef1277a5e1d5deef7420281eafade2e2614.tar.bz2 |
debuggerd: Incorporate liblog reading API
(cherry picked from commit a63f927ce10817ce637dd52ba2f4ac763ce4fc61)
Change-Id: Ic26e9dba3b45c827d122b03e34cc4a5bd48f7deb
Diffstat (limited to 'debuggerd')
-rw-r--r-- | debuggerd/tombstone.cpp | 97 |
1 files changed, 38 insertions, 59 deletions
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp index acb6ed6..436b845 100644 --- a/debuggerd/tombstone.cpp +++ b/debuggerd/tombstone.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2012-2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ #include <private/android_filesystem_config.h> +#include <log/log.h> #include <log/logger.h> #include <cutils/properties.h> @@ -453,43 +454,40 @@ static bool dump_sibling_thread_report( // Reads the contents of the specified log device, filters out the entries // that don't match the specified pid, and writes them to the tombstone file. // -// If "tailOnly" is set, we only print the last few lines. -static void dump_log_file(log_t* log, pid_t pid, const char* filename, bool tailOnly) { +// If "tail" is set, we only print the last few lines. +static void dump_log_file(log_t* log, pid_t pid, const char* filename, + unsigned int tail) { bool first = true; + struct logger_list *logger_list; - // circular buffer, for "tailOnly" mode - const int kShortLogMaxLines = 5; - const int kShortLogLineLen = 256; - char shortLog[kShortLogMaxLines][kShortLogLineLen]; - int shortLogCount = 0; - int shortLogNext = 0; + logger_list = android_logger_list_open( + android_name_to_log_id(filename), O_RDONLY | O_NONBLOCK, tail, pid); - int logfd = open(filename, O_RDONLY | O_NONBLOCK); - if (logfd < 0) { + if (!logger_list) { XLOG("Unable to open %s: %s\n", filename, strerror(errno)); return; } - union { - unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1]; - struct logger_entry entry; - } log_entry; + struct log_msg log_entry; while (true) { - ssize_t actual = read(logfd, log_entry.buf, LOGGER_ENTRY_MAX_LEN); + ssize_t actual = android_logger_list_read(logger_list, &log_entry); + if (actual < 0) { - if (errno == EINTR) { + if (actual == -EINTR) { // interrupted by signal, retry continue; - } else if (errno == EAGAIN) { + } else if (actual == -EAGAIN) { // non-blocking EOF; we're done break; } else { - _LOG(log, 0, "Error while reading log: %s\n", strerror(errno)); + _LOG(log, 0, "Error while reading log: %s\n", + strerror(-actual)); break; } } else if (actual == 0) { - _LOG(log, 0, "Got zero bytes while reading log: %s\n", strerror(errno)); + _LOG(log, 0, "Got zero bytes while reading log: %s\n", + strerror(errno)); break; } @@ -497,7 +495,7 @@ static void dump_log_file(log_t* log, pid_t pid, const char* filename, bool tail // because you will be writing as fast as you're reading. Any // high-frequency debug diagnostics should just be written to // the tombstone file. - struct logger_entry* entry = &log_entry.entry; + struct logger_entry* entry = &log_entry.entry_v1; if (entry->pid != static_cast<int32_t>(pid)) { // wrong pid, ignore @@ -505,7 +503,8 @@ static void dump_log_file(log_t* log, pid_t pid, const char* filename, bool tail } if (first) { - _LOG(log, 0, "--------- %slog %s\n", tailOnly ? "tail end of " : "", filename); + _LOG(log, 0, "--------- %slog %s\n", + tail ? "tail end of " : "", filename); first = false; } @@ -517,9 +516,14 @@ static void dump_log_file(log_t* log, pid_t pid, const char* filename, bool tail // TODO: scan for line breaks ('\n') and display each text line // on a separate line, prefixed with the header, like logcat does. static const char* kPrioChars = "!.VDIWEFS"; - unsigned char prio = entry->msg[0]; - char* tag = entry->msg + 1; - char* msg = tag + strlen(tag) + 1; + unsigned hdr_size = log_entry.entry.hdr_size; + if (!hdr_size) { + hdr_size = sizeof(log_entry.entry_v1); + } + char* msg = (char *)log_entry.buf + hdr_size; + unsigned char prio = msg[0]; + char* tag = msg + 1; + msg = tag + strlen(tag) + 1; // consume any trailing newlines char* eatnl = msg + strlen(msg) - 1; @@ -536,44 +540,19 @@ static void dump_log_file(log_t* log, pid_t pid, const char* filename, bool tail ptm = localtime_r(&sec, &tmBuf); strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); - if (tailOnly) { - snprintf(shortLog[shortLogNext], kShortLogLineLen, - "%s.%03d %5d %5d %c %-8s: %s", - timeBuf, entry->nsec / 1000000, entry->pid, entry->tid, - prioChar, tag, msg); - shortLogNext = (shortLogNext + 1) % kShortLogMaxLines; - shortLogCount++; - } else { - _LOG(log, 0, "%s.%03d %5d %5d %c %-8s: %s\n", - timeBuf, entry->nsec / 1000000, entry->pid, entry->tid, prioChar, tag, msg); - } - } - - if (tailOnly) { - int i; - - // If we filled the buffer, we want to start at "next", which has - // the oldest entry. If we didn't, we want to start at zero. - if (shortLogCount < kShortLogMaxLines) { - shortLogNext = 0; - } else { - shortLogCount = kShortLogMaxLines; // cap at window size - } - - for (i = 0; i < shortLogCount; i++) { - _LOG(log, 0, "%s\n", shortLog[shortLogNext]); - shortLogNext = (shortLogNext + 1) % kShortLogMaxLines; - } + _LOG(log, 0, "%s.%03d %5d %5d %c %-8s: %s\n", + timeBuf, entry->nsec / 1000000, entry->pid, entry->tid, + prioChar, tag, msg); } - close(logfd); + android_logger_list_free(logger_list); } // Dumps the logs generated by the specified pid to the tombstone, from both // "system" and "main" log devices. Ideally we'd interleave the output. -static void dump_logs(log_t* log, pid_t pid, bool tailOnly) { - dump_log_file(log, pid, "/dev/log/system", tailOnly); - dump_log_file(log, pid, "/dev/log/main", tailOnly); +static void dump_logs(log_t* log, pid_t pid, unsigned tail) { + dump_log_file(log, pid, "system", tail); + dump_log_file(log, pid, "main", tail); } static void dump_abort_message(Backtrace* backtrace, log_t* log, uintptr_t address) { @@ -649,7 +628,7 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t a } if (want_logs) { - dump_logs(log, pid, true); + dump_logs(log, pid, 5); } bool detach_failed = false; @@ -661,7 +640,7 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t a delete map; if (want_logs) { - dump_logs(log, pid, false); + dump_logs(log, pid, 0); } // send EOD to the Activity Manager, then wait for its ack to avoid racing ahead |