diff options
author | Andreas Gampe <agampe@google.com> | 2016-09-08 11:03:58 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2016-09-08 15:33:27 -0700 |
commit | 2691e335feec4806439054b5c6fe3e7a06cdd695 (patch) | |
tree | e85bf607e6eed9c2abcd2fbfbf538713eb046c52 | |
parent | 88b5af68bd5f272d72aab23e9aedad3ea929fe54 (diff) | |
download | core-2691e335feec4806439054b5c6fe3e7a06cdd695.tar.gz core-2691e335feec4806439054b5c6fe3e7a06cdd695.tar.bz2 core-2691e335feec4806439054b5c6fe3e7a06cdd695.zip |
Base: Add AbortFunction for logging
Add a hook to modify FATAL behavior. Add a test.
Bug: 31338270
Test: m
Test: mmma system/core/base && $ANDROID_HOST_OUT/nativetest64/libbase_test/libbase_test64
Change-Id: I966da319cda613738b3f2ccdac8c21900d6a5c72
-rw-r--r-- | base/include/android-base/logging.h | 24 | ||||
-rw-r--r-- | base/logging.cpp | 27 | ||||
-rw-r--r-- | base/logging_test.cpp | 20 |
3 files changed, 56 insertions, 15 deletions
diff --git a/base/include/android-base/logging.h b/base/include/android-base/logging.h index c626fc353..39f468977 100644 --- a/base/include/android-base/logging.h +++ b/base/include/android-base/logging.h @@ -51,12 +51,15 @@ enum LogId { SYSTEM, }; -typedef std::function<void(LogId, LogSeverity, const char*, const char*, - unsigned int, const char*)> LogFunction; +using LogFunction = std::function<void(LogId, LogSeverity, const char*, const char*, + unsigned int, const char*)>; +using AbortFunction = std::function<void(const char*)>; void KernelLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*); void StderrLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*); +void DefaultAborter(const char* abort_message); + #ifdef __ANDROID__ // We expose this even though it is the default because a user that wants to // override the default log buffer will have to construct this themselves. @@ -80,15 +83,22 @@ class LogdLogger { // The tag (or '*' for the global level) comes first, followed by a colon and a // letter indicating the minimum priority level we're expected to log. This can // be used to reveal or conceal logs with specific tags. -void InitLogging(char* argv[], LogFunction&& logger); - -// Configures logging using the default logger (logd for the device, stderr for -// the host). -void InitLogging(char* argv[]); +#ifdef __ANDROID__ +#define INIT_LOGGING_DEFAULT_LOGGER LogdLogger() +#else +#define INIT_LOGGING_DEFAULT_LOGGER StderrLogger +#endif +void InitLogging(char* argv[], + LogFunction&& logger = INIT_LOGGING_DEFAULT_LOGGER, + AbortFunction&& aborter = DefaultAborter); +#undef INIT_LOGGING_DEFAULT_LOGGER // Replace the current logger. void SetLogger(LogFunction&& logger); +// Replace the current aborter. +void SetAborter(AbortFunction&& aborter); + class ErrnoRestorer { public: ErrnoRestorer() diff --git a/base/logging.cpp b/base/logging.cpp index 86d3b4d26..6e1dd9ca3 100644 --- a/base/logging.cpp +++ b/base/logging.cpp @@ -173,6 +173,8 @@ static auto& gLogger = *new LogFunction(LogdLogger()); static auto& gLogger = *new LogFunction(StderrLogger); #endif +static auto& gAborter = *new AbortFunction(DefaultAborter); + static bool gInitialized = false; static LogSeverity gMinimumLogSeverity = INFO; static auto& gProgramInvocationName = *new std::unique_ptr<std::string>(); @@ -247,6 +249,15 @@ void StderrLogger(LogId, LogSeverity severity, const char*, const char* file, severity_char, timestamp, getpid(), GetThreadId(), file, line, message); } +void DefaultAborter(const char* abort_message) { +#ifdef __ANDROID__ + android_set_abort_message(abort_message); +#else + UNUSED(abort_message); +#endif + abort(); +} + #ifdef __ANDROID__ LogdLogger::LogdLogger(LogId default_log_id) : default_log_id_(default_log_id) { @@ -284,12 +295,10 @@ void LogdLogger::operator()(LogId id, LogSeverity severity, const char* tag, } #endif -void InitLogging(char* argv[], LogFunction&& logger) { +void InitLogging(char* argv[], LogFunction&& logger, AbortFunction&& aborter) { SetLogger(std::forward<LogFunction>(logger)); - InitLogging(argv); -} + SetAborter(std::forward<AbortFunction>(aborter)); -void InitLogging(char* argv[]) { if (gInitialized) { return; } @@ -349,6 +358,11 @@ void SetLogger(LogFunction&& logger) { gLogger = std::move(logger); } +void SetAborter(AbortFunction&& aborter) { + lock_guard<mutex> lock(logging_lock); + gAborter = std::move(aborter); +} + static const char* GetFileBasename(const char* file) { // We can't use basename(3) even on Unix because the Mac doesn't // have a non-modifying basename. @@ -450,10 +464,7 @@ LogMessage::~LogMessage() { // Abort if necessary. if (data_->GetSeverity() == FATAL) { -#ifdef __ANDROID__ - android_set_abort_message(msg.c_str()); -#endif - abort(); + gAborter(msg.c_str()); } } diff --git a/base/logging_test.cpp b/base/logging_test.cpp index 3fde302a3..02a919870 100644 --- a/base/logging_test.cpp +++ b/base/logging_test.cpp @@ -330,3 +330,23 @@ TEST(logging, UNIMPLEMENTED) { UNIMPLEMENTED(ERROR); CheckMessage(cap, android::base::ERROR, expected.c_str()); } + +static void NoopAborter(const char* msg ATTRIBUTE_UNUSED) { + LOG(ERROR) << "called noop"; +} + +TEST(logging, LOG_FATAL_NOOP_ABORTER) { + { + android::base::SetAborter(NoopAborter); + + android::base::ScopedLogSeverity sls(android::base::ERROR); + CapturedStderr cap; + LOG(FATAL) << "foobar"; + CheckMessage(cap, android::base::FATAL, "foobar"); + CheckMessage(cap, android::base::ERROR, "called noop"); + + android::base::SetAborter(android::base::DefaultAborter); + } + + ASSERT_DEATH({SuppressAbortUI(); LOG(FATAL) << "foobar";}, "foobar"); +} |