diff options
author | 2017-06-01 20:14:58 -0700 | |
---|---|---|
committer | 2017-06-01 20:14:58 -0700 | |
commit | c6fe427cccc166ece2d57bc45e91a8f5aad0661b (patch) | |
tree | 73b4cd6a069f494fea1d3f9f40a3bac6290e1e87 | |
parent | 596c58b3dc73a4017d49af6c5037bbd7109fd31e (diff) |
ART: Refactor HandleUnexpectedSignalCommon
Avoid the std::ostringstream. Instead use a lambda and immediately
use std::cerr when asked to dump there, eventually.
Also refactor the signature to make it more explicit what the function
will handle and where it would dump to.
Test: m test-art-host
Change-Id: I2be5497d4f9957127243879113372d9aa1535d82
-rw-r--r-- | runtime/runtime_android.cc | 6 | ||||
-rw-r--r-- | runtime/runtime_common.cc | 62 | ||||
-rw-r--r-- | runtime/runtime_common.h | 3 | ||||
-rw-r--r-- | runtime/runtime_linux.cc | 8 |
4 files changed, 45 insertions, 34 deletions
diff --git a/runtime/runtime_android.cc b/runtime/runtime_android.cc index 495296cf7d..4bd3b3ae3a 100644 --- a/runtime/runtime_android.cc +++ b/runtime/runtime_android.cc @@ -27,7 +27,11 @@ namespace art { struct sigaction old_action; void HandleUnexpectedSignalAndroid(int signal_number, siginfo_t* info, void* raw_context) { - HandleUnexpectedSignalCommon(signal_number, info, raw_context, /* running_on_linux */ false); + HandleUnexpectedSignalCommon(signal_number, + info, + raw_context, + /* handle_timeout_signal */ false, + /* dump_on_stderr */ false); // Run the old signal handler. old_action.sa_sigaction(signal_number, info, raw_context); diff --git a/runtime/runtime_common.cc b/runtime/runtime_common.cc index 36901293bb..5511fb7b6d 100644 --- a/runtime/runtime_common.cc +++ b/runtime/runtime_common.cc @@ -370,10 +370,8 @@ static bool IsTimeoutSignal(int signal_number) { void HandleUnexpectedSignalCommon(int signal_number, siginfo_t* info, void* raw_context, - bool running_on_linux) { - bool handle_timeout_signal = running_on_linux; - bool dump_on_stderr = running_on_linux; - + bool handle_timeout_signal, + bool dump_on_stderr) { static bool handling_unexpected_signal = false; if (handling_unexpected_signal) { LogHelper::LogLineLowStack(__FILE__, @@ -393,39 +391,41 @@ void HandleUnexpectedSignalCommon(int signal_number, gAborting++; // set before taking any locks MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_); - bool has_address = (signal_number == SIGILL || signal_number == SIGBUS || - signal_number == SIGFPE || signal_number == SIGSEGV); + auto logger = [&](auto& stream) { + bool has_address = (signal_number == SIGILL || signal_number == SIGBUS || + signal_number == SIGFPE || signal_number == SIGSEGV); + OsInfo os_info; + const char* cmd_line = GetCmdLine(); + if (cmd_line == nullptr) { + cmd_line = "<unset>"; // Because no-one called InitLogging. + } + pid_t tid = GetTid(); + std::string thread_name(GetThreadName(tid)); + UContext thread_context(raw_context); + Backtrace thread_backtrace(raw_context); + + stream << "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***" << std::endl + << StringPrintf("Fatal signal %d (%s), code %d (%s)", + signal_number, + GetSignalName(signal_number), + info->si_code, + GetSignalCodeName(signal_number, info->si_code)) + << (has_address ? StringPrintf(" fault addr %p", info->si_addr) : "") << std::endl + << "OS: " << Dumpable<OsInfo>(os_info) << std::endl + << "Cmdline: " << cmd_line << std::endl + << "Thread: " << tid << " \"" << thread_name << "\"" << std::endl + << "Registers:\n" << Dumpable<UContext>(thread_context) << std::endl + << "Backtrace:\n" << Dumpable<Backtrace>(thread_backtrace) << std::endl; + stream << std::flush; + }; - OsInfo os_info; - const char* cmd_line = GetCmdLine(); - if (cmd_line == nullptr) { - cmd_line = "<unset>"; // Because no-one called InitLogging. - } - pid_t tid = GetTid(); - std::string thread_name(GetThreadName(tid)); - UContext thread_context(raw_context); - Backtrace thread_backtrace(raw_context); - - std::ostringstream stream; - stream << "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n" - << StringPrintf("Fatal signal %d (%s), code %d (%s)", - signal_number, - GetSignalName(signal_number), - info->si_code, - GetSignalCodeName(signal_number, info->si_code)) - << (has_address ? StringPrintf(" fault addr %p", info->si_addr) : "") << '\n' - << "OS: " << Dumpable<OsInfo>(os_info) << '\n' - << "Cmdline: " << cmd_line << '\n' - << "Thread: " << tid << " \"" << thread_name << "\"" << '\n' - << "Registers:\n" << Dumpable<UContext>(thread_context) << '\n' - << "Backtrace:\n" << Dumpable<Backtrace>(thread_backtrace) << '\n'; if (dump_on_stderr) { // Note: We are using cerr directly instead of LOG macros to ensure even just partial output // makes it out. That means we lose the "dalvikvm..." prefix, but that is acceptable // considering this is an abort situation. - std::cerr << stream.str() << std::flush; + logger(std::cerr); } else { - LOG(FATAL_WITHOUT_ABORT) << stream.str() << std::flush; + logger(LOG_STREAM(FATAL_WITHOUT_ABORT)); } if (kIsDebugBuild && signal_number == SIGSEGV) { PrintFileToLog("/proc/self/maps", LogSeverity::FATAL_WITHOUT_ABORT); diff --git a/runtime/runtime_common.h b/runtime/runtime_common.h index 832b6bbf3e..06d66270af 100644 --- a/runtime/runtime_common.h +++ b/runtime/runtime_common.h @@ -68,7 +68,8 @@ int GetTimeoutSignal(); void HandleUnexpectedSignalCommon(int signal_number, siginfo_t* info, void* raw_context, - bool running_on_linux); + bool handle_timeout_signal, + bool dump_on_stderr); void InitPlatformSignalHandlersCommon(void (*newact)(int, siginfo_t*, void*), struct sigaction* oldact, diff --git a/runtime/runtime_linux.cc b/runtime/runtime_linux.cc index ad61cf373b..424dcf85cf 100644 --- a/runtime/runtime_linux.cc +++ b/runtime/runtime_linux.cc @@ -25,7 +25,13 @@ namespace art { void HandleUnexpectedSignalLinux(int signal_number, siginfo_t* info, void* raw_context) { - HandleUnexpectedSignalCommon(signal_number, info, raw_context, /* running_on_linux */ true); + // Linux is mainly used for host testing. Under those conditions, react to the timeout signal, + // and dump to stderr to avoid missing output on double-faults. + HandleUnexpectedSignalCommon(signal_number, + info, + raw_context, + /* handle_timeout_signal */ true, + /* dump_on_stderr */ true); if (getenv("debug_db_uid") != nullptr || getenv("art_wait_for_gdb_on_crash") != nullptr) { pid_t tid = GetTid(); |