diff options
author | 2012-11-27 15:19:57 -0800 | |
---|---|---|
committer | 2012-11-27 15:37:00 -0800 | |
commit | af1b89281fd1f86efeb791b61f5a3f2031c70312 (patch) | |
tree | a4f00e84271f267404a082c954f7416d5bcd3e0e | |
parent | 9c85bc0b6577ee00e4e2d3ee9a7d0fd72d7a4966 (diff) |
Prevent hang due to HandleUnexpectedSignal reentry
Change-Id: I0fe6a9b642e8d866aba893906c36bca6f1a4334e
-rw-r--r-- | src/logging.cc | 13 | ||||
-rw-r--r-- | src/logging.h | 16 | ||||
-rw-r--r-- | src/logging_android.cc | 12 | ||||
-rw-r--r-- | src/logging_linux.cc | 12 | ||||
-rw-r--r-- | src/runtime_linux.cc | 10 |
5 files changed, 33 insertions, 30 deletions
diff --git a/src/logging.cc b/src/logging.cc index 9dde963895..12d1fa46df 100644 --- a/src/logging.cc +++ b/src/logging.cc @@ -94,6 +94,15 @@ void InitLogging(char* argv[]) { } } +LogMessageData::LogMessageData(const char* file, int line, LogSeverity severity, int error) + : file(file), + line_number(line), + severity(severity), + error(error) { + const char* last_slash = strrchr(file, '/'); + file = (last_slash == NULL) ? file : last_slash + 1; +} + LogMessage::~LogMessage() { if (data_->severity < gMinimumLogSeverity) { return; // No need to format something we're not going to output. @@ -109,14 +118,14 @@ LogMessage::~LogMessage() { { MutexLock mu(Thread::Current(), *Locks::logging_lock_); if (msg.find('\n') == std::string::npos) { - LogLine(msg.c_str()); + LogLine(*data_, msg.c_str()); } else { msg += '\n'; size_t i = 0; while (i < msg.size()) { size_t nl = msg.find('\n', i); msg[nl] = '\0'; - LogLine(&msg[i]); + LogLine(*data_, &msg[i]); i = nl + 1; } } diff --git a/src/logging.h b/src/logging.h index d0d35ea453..1c04b2cc2a 100644 --- a/src/logging.h +++ b/src/logging.h @@ -21,6 +21,7 @@ #include <cstring> #include <iostream> // NOLINT #include <sstream> +#include <signal.h> #include "log_severity.h" #include "macros.h" @@ -167,13 +168,7 @@ EAGER_PTR_EVALUATOR(signed char*, signed char*); // lots of checks/logging in a function. struct LogMessageData { public: - LogMessageData(int line, LogSeverity severity, int error) - : file(NULL), - line_number(line), - severity(severity), - error(error) { - } - + LogMessageData(const char* file, int line, LogSeverity severity, int error); std::ostringstream buffer; const char* file; int line_number; @@ -186,15 +181,18 @@ struct LogMessageData { class LogMessage { public: - LogMessage(const char* file, int line, LogSeverity severity, int error); + LogMessage(const char* file, int line, LogSeverity severity, int error) + : data_(new LogMessageData(file, line, severity, error)) { + } ~LogMessage() LOCKS_EXCLUDED(Locks::logging_lock_); std::ostream& stream(); private: - void LogLine(const char*); + static void LogLine(const LogMessageData& data, const char*); LogMessageData* data_; + friend void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context); DISALLOW_COPY_AND_ASSIGN(LogMessage); }; diff --git a/src/logging_android.cc b/src/logging_android.cc index 7007d7aed4..0acf5f9e2f 100644 --- a/src/logging_android.cc +++ b/src/logging_android.cc @@ -29,17 +29,11 @@ static const int kLogSeverityToAndroidLogPriority[] = { ANDROID_LOG_ERROR, ANDROID_LOG_FATAL, ANDROID_LOG_FATAL }; -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, int error) - : data_(new LogMessageData(line, severity, error)) { - const char* last_slash = strrchr(file, '/'); - data_->file = (last_slash == NULL) ? file : last_slash + 1; -} - -void LogMessage::LogLine(const char* message) { +void LogMessage::LogLine(const LogMessageData& data, const char* message) { const char* tag = ProgramInvocationShortName(); - int priority = kLogSeverityToAndroidLogPriority[data_->severity]; + int priority = kLogSeverityToAndroidLogPriority[data.severity]; if (priority == ANDROID_LOG_FATAL) { - LOG_PRI(priority, tag, "%s:%d] %s", data_->file, data_->line_number, message); + LOG_PRI(priority, tag, "%s:%d] %s", data.file, data.line_number, message); } else { LOG_PRI(priority, tag, "%s", message); } diff --git a/src/logging_linux.cc b/src/logging_linux.cc index 0d7fc0bd5d..789c083b98 100644 --- a/src/logging_linux.cc +++ b/src/logging_linux.cc @@ -27,17 +27,11 @@ namespace art { -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, int error) - : data_(new LogMessageData(line, severity, error)) { - const char* last_slash = strrchr(file, '/'); - data_->file = (last_slash == NULL) ? file : last_slash + 1; -} - -void LogMessage::LogLine(const char* message) { - char severity = "VDIWEFF"[data_->severity]; +void LogMessage::LogLine(const LogMessageData& data, const char* message) { + char severity = "VDIWEFF"[data.severity]; fprintf(stderr, "%s %c %5d %5d %s:%d] %s\n", ProgramInvocationShortName(), severity, getpid(), ::art::GetTid(), - data_->file, data_->line_number, message); + data.file, data.line_number, message); } } // namespace art diff --git a/src/runtime_linux.cc b/src/runtime_linux.cc index 430c70f4d9..72989a6c23 100644 --- a/src/runtime_linux.cc +++ b/src/runtime_linux.cc @@ -227,7 +227,15 @@ struct UContext { mcontext_t& context; }; -static void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) { +void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) { + static bool handlingUnexpectedSignal = false; + if (handlingUnexpectedSignal) { + LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1); + LogMessage::LogLine(data, "HandleUnexpectedSignal reentered\n"); + _exit(1); + } + handlingUnexpectedSignal = true; + gAborting = true; // set before taking any locks MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_); |