diff --git a/src/logging.cc b/src/logging.cc index e0353e2..ddcf910 100644 --- a/src/logging.cc +++ b/src/logging.cc @@ -495,7 +495,7 @@ class LogDestination { private: LogDestination(LogSeverity severity, const char* base_filename); - ~LogDestination() { } + ~LogDestination(); // Take a log message of a particular severity and log it to stderr // iff it's of a high enough severity to deserve it. @@ -582,6 +582,13 @@ LogDestination::LogDestination(LogSeverity severity, logger_(&fileobject_) { } +LogDestination::~LogDestination() { + if (logger_ && logger_ != &fileobject_) { + // Delete user-specified logger set via SetLogger(). + delete logger_; + } +} + inline void LogDestination::FlushLogFilesUnsafe(int min_severity) { // assume we have the log_mutex or we simply don't care // about it diff --git a/src/logging_unittest.cc b/src/logging_unittest.cc index a980677..73d426b 100644 --- a/src/logging_unittest.cc +++ b/src/logging_unittest.cc @@ -114,6 +114,7 @@ static void TestExtension(); static void TestWrapper(); static void TestErrno(); static void TestTruncate(); +static void TestCustomLoggerDeletionOnShutdown(); static int x = -1; static void BM_Check1(int n) { @@ -241,8 +242,7 @@ int main(int argc, char **argv) { TestWrapper(); TestErrno(); TestTruncate(); - - ShutdownGoogleLogging(); + TestCustomLoggerDeletionOnShutdown(); fprintf(stdout, "PASS\n"); return 0; @@ -937,6 +937,39 @@ static void TestTruncate() { #endif } +struct RecordDeletionLogger : public base::Logger { + RecordDeletionLogger(bool* set_on_destruction, + base::Logger* wrapped_logger) : + set_on_destruction_(set_on_destruction), + wrapped_logger_(wrapped_logger) + { + *set_on_destruction_ = false; + } + virtual ~RecordDeletionLogger() { + *set_on_destruction_ = true; + } + virtual void Write(bool force_flush, + time_t timestamp, + const char* message, + int length) { + wrapped_logger_->Write(force_flush, timestamp, message, length); + } + virtual void Flush() { wrapped_logger_->Flush(); } + virtual uint32 LogSize() { return wrapped_logger_->LogSize(); } + private: + bool* set_on_destruction_; + base::Logger* wrapped_logger_; +}; + +static void TestCustomLoggerDeletionOnShutdown() { + bool custom_logger_deleted = false; + base::SetLogger(GLOG_INFO, + new RecordDeletionLogger(&custom_logger_deleted, + base::GetLogger(GLOG_INFO))); + ShutdownGoogleLogging(); + EXPECT_TRUE(custom_logger_deleted); +} + _START_GOOGLE_NAMESPACE_ namespace glog_internal_namespace_ { extern // in logging.cc