Merge "Base: Add AbortFunction for logging"
This commit is contained in:
commit
318cc3c03a
3 changed files with 56 additions and 15 deletions
|
|
@ -51,12 +51,15 @@ enum LogId {
|
||||||
SYSTEM,
|
SYSTEM,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::function<void(LogId, LogSeverity, const char*, const char*,
|
using LogFunction = std::function<void(LogId, LogSeverity, const char*, const char*,
|
||||||
unsigned int, const char*)> LogFunction;
|
unsigned int, const char*)>;
|
||||||
|
using AbortFunction = std::function<void(const char*)>;
|
||||||
|
|
||||||
void KernelLogger(LogId, LogSeverity, const char*, const char*, unsigned int, 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 StderrLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*);
|
||||||
|
|
||||||
|
void DefaultAborter(const char* abort_message);
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
// We expose this even though it is the default because a user that wants to
|
// 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.
|
// 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
|
// 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
|
// letter indicating the minimum priority level we're expected to log. This can
|
||||||
// be used to reveal or conceal logs with specific tags.
|
// be used to reveal or conceal logs with specific tags.
|
||||||
void InitLogging(char* argv[], LogFunction&& logger);
|
#ifdef __ANDROID__
|
||||||
|
#define INIT_LOGGING_DEFAULT_LOGGER LogdLogger()
|
||||||
// Configures logging using the default logger (logd for the device, stderr for
|
#else
|
||||||
// the host).
|
#define INIT_LOGGING_DEFAULT_LOGGER StderrLogger
|
||||||
void InitLogging(char* argv[]);
|
#endif
|
||||||
|
void InitLogging(char* argv[],
|
||||||
|
LogFunction&& logger = INIT_LOGGING_DEFAULT_LOGGER,
|
||||||
|
AbortFunction&& aborter = DefaultAborter);
|
||||||
|
#undef INIT_LOGGING_DEFAULT_LOGGER
|
||||||
|
|
||||||
// Replace the current logger.
|
// Replace the current logger.
|
||||||
void SetLogger(LogFunction&& logger);
|
void SetLogger(LogFunction&& logger);
|
||||||
|
|
||||||
|
// Replace the current aborter.
|
||||||
|
void SetAborter(AbortFunction&& aborter);
|
||||||
|
|
||||||
class ErrnoRestorer {
|
class ErrnoRestorer {
|
||||||
public:
|
public:
|
||||||
ErrnoRestorer()
|
ErrnoRestorer()
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,8 @@ static auto& gLogger = *new LogFunction(LogdLogger());
|
||||||
static auto& gLogger = *new LogFunction(StderrLogger);
|
static auto& gLogger = *new LogFunction(StderrLogger);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static auto& gAborter = *new AbortFunction(DefaultAborter);
|
||||||
|
|
||||||
static bool gInitialized = false;
|
static bool gInitialized = false;
|
||||||
static LogSeverity gMinimumLogSeverity = INFO;
|
static LogSeverity gMinimumLogSeverity = INFO;
|
||||||
static auto& gProgramInvocationName = *new std::unique_ptr<std::string>();
|
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);
|
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__
|
#ifdef __ANDROID__
|
||||||
LogdLogger::LogdLogger(LogId default_log_id) : default_log_id_(default_log_id) {
|
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
|
#endif
|
||||||
|
|
||||||
void InitLogging(char* argv[], LogFunction&& logger) {
|
void InitLogging(char* argv[], LogFunction&& logger, AbortFunction&& aborter) {
|
||||||
SetLogger(std::forward<LogFunction>(logger));
|
SetLogger(std::forward<LogFunction>(logger));
|
||||||
InitLogging(argv);
|
SetAborter(std::forward<AbortFunction>(aborter));
|
||||||
}
|
|
||||||
|
|
||||||
void InitLogging(char* argv[]) {
|
|
||||||
if (gInitialized) {
|
if (gInitialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -349,6 +358,11 @@ void SetLogger(LogFunction&& logger) {
|
||||||
gLogger = std::move(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) {
|
static const char* GetFileBasename(const char* file) {
|
||||||
// We can't use basename(3) even on Unix because the Mac doesn't
|
// We can't use basename(3) even on Unix because the Mac doesn't
|
||||||
// have a non-modifying basename.
|
// have a non-modifying basename.
|
||||||
|
|
@ -450,10 +464,7 @@ LogMessage::~LogMessage() {
|
||||||
|
|
||||||
// Abort if necessary.
|
// Abort if necessary.
|
||||||
if (data_->GetSeverity() == FATAL) {
|
if (data_->GetSeverity() == FATAL) {
|
||||||
#ifdef __ANDROID__
|
gAborter(msg.c_str());
|
||||||
android_set_abort_message(msg.c_str());
|
|
||||||
#endif
|
|
||||||
abort();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -330,3 +330,23 @@ TEST(logging, UNIMPLEMENTED) {
|
||||||
UNIMPLEMENTED(ERROR);
|
UNIMPLEMENTED(ERROR);
|
||||||
CheckMessage(cap, android::base::ERROR, expected.c_str());
|
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");
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue