Prevent hang due to HandleUnexpectedSignal reentry
Change-Id: I0fe6a9b642e8d866aba893906c36bca6f1a4334e
diff --git a/src/logging.cc b/src/logging.cc
index 9dde963..12d1fa4 100644
--- a/src/logging.cc
+++ b/src/logging.cc
@@ -94,6 +94,15 @@
}
}
+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 @@
{
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 d0d35ea..1c04b2c 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 @@
// 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 @@
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 7007d7a..0acf5f9 100644
--- a/src/logging_android.cc
+++ b/src/logging_android.cc
@@ -29,17 +29,11 @@
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 0d7fc0b..789c083 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 430c70f..72989a6 100644
--- a/src/runtime_linux.cc
+++ b/src/runtime_linux.cc
@@ -227,7 +227,15 @@
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_);