diff options
| author | 2013-05-16 11:19:53 -0700 | |
|---|---|---|
| committer | 2013-05-16 11:26:24 -0700 | |
| commit | c4ee12e73fc844f28a9812a9141985cf05143a57 (patch) | |
| tree | 59ea9f105b39b05beea9ff17cda83f1122461629 /src | |
| parent | d8274bcbc565fff1254574b3cbf46dc4e7b52812 (diff) | |
Avoid recursion if logging lock is corrupt.
If the logging lock is corrupt then using LOG fails and recursive death ensues.
Make Mutex a friend of LogMessage so that it can do raw logging in this special
situation.
Opportunistically also make fields of LogMessage and LogMessageData that can be
const, const.
Change-Id: I9e0d07c3224096bcf03d6410cd64bb8b5c831fac
Diffstat (limited to 'src')
| -rw-r--r-- | src/base/logging.h | 11 | ||||
| -rw-r--r-- | src/base/mutex.cc | 10 |
2 files changed, 15 insertions, 6 deletions
diff --git a/src/base/logging.h b/src/base/logging.h index 310357d11b..f250ce01b3 100644 --- a/src/base/logging.h +++ b/src/base/logging.h @@ -170,10 +170,10 @@ struct LogMessageData { public: LogMessageData(const char* file, int line, LogSeverity severity, int error); std::ostringstream buffer; - const char* file; - int line_number; - LogSeverity severity; - int error; + const char* const file; + const int line_number; + const LogSeverity severity; + const int error; private: DISALLOW_COPY_AND_ASSIGN(LogMessageData); @@ -190,9 +190,10 @@ class LogMessage { private: static void LogLine(const LogMessageData& data, const char*); - LogMessageData* data_; + LogMessageData* const data_; friend void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context); + friend class Mutex; DISALLOW_COPY_AND_ASSIGN(LogMessage); }; diff --git a/src/base/mutex.cc b/src/base/mutex.cc index 86356a9b85..a2851e5b3c 100644 --- a/src/base/mutex.cc +++ b/src/base/mutex.cc @@ -394,7 +394,15 @@ void Mutex::ExclusiveUnlock(Thread* self) { } } } else { - LOG(FATAL) << "Unexpected state_:" << cur_state << " for " << name_; + // Logging acquires the logging lock, avoid infinite recursion in that case. + if (this != Locks::logging_lock_) { + LOG(FATAL) << "Unexpected state_ in unlock " << cur_state << " for " << name_; + } else { + LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1); + LogMessage::LogLine(data, StringPrintf("Unexpected state_ %d in unlock for %s", + cur_state, name_).c_str()); + _exit(1); + } } } while(!done); #else |