diff options
author | Andreas Gampe <agampe@google.com> | 2015-01-07 22:08:35 -0800 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2015-01-08 09:35:31 -0800 |
commit | 628a61ac52a8a314e74ab445397add60b4e72a5b (patch) | |
tree | df78aa48e31e58669c6ae63ace7ba6bb532ec65d | |
parent | 4270e74152d8a7cd979ab5a92fe2a8f84adb8a42 (diff) | |
download | art-628a61ac52a8a314e74ab445397add60b4e72a5b.zip art-628a61ac52a8a314e74ab445397add60b4e72a5b.tar.gz art-628a61ac52a8a314e74ab445397add60b4e72a5b.tar.bz2 |
ART: Pass ucontext to Backtrace in Stack Dump
In case of an unexpected signal on the host we dump the thread stack
ourselves. We have to pass the context given to the signal handler,
as the signal handler is run on an alternate stack. Otherwise
libbacktrace can't dump the actual faulty part.
Bug: 18933933
Change-Id: Id2710d2fd44b7c3b3335973a9288979a5793638b
-rw-r--r-- | runtime/runtime_linux.cc | 11 | ||||
-rw-r--r-- | runtime/utils.cc | 4 | ||||
-rw-r--r-- | runtime/utils.h | 2 |
3 files changed, 12 insertions, 5 deletions
diff --git a/runtime/runtime_linux.cc b/runtime/runtime_linux.cc index 1de035c..a5a0204 100644 --- a/runtime/runtime_linux.cc +++ b/runtime/runtime_linux.cc @@ -35,9 +35,16 @@ namespace art { static constexpr bool kDumpHeapObjectOnSigsevg = false; struct Backtrace { + public: + explicit Backtrace(void* raw_context) : raw_context_(raw_context) {} void Dump(std::ostream& os) const { - DumpNativeStack(os, GetTid(), "\t"); + DumpNativeStack(os, GetTid(), "\t", nullptr, raw_context_); } + private: + // Stores the context of the signal that was unexpected and will terminate the runtime. The + // DumpNativeStack code will take care of casting it to the expected type. This is required + // as our signal handler runs on an alternate stack. + void* raw_context_; }; struct OsInfo { @@ -298,7 +305,7 @@ void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_contex pid_t tid = GetTid(); std::string thread_name(GetThreadName(tid)); UContext thread_context(raw_context); - Backtrace thread_backtrace; + Backtrace thread_backtrace(raw_context); LOG(INTERNAL_FATAL) << "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n" << StringPrintf("Fatal signal %d (%s), code %d (%s)", diff --git a/runtime/utils.cc b/runtime/utils.cc index 1211547..7234ec0 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -1118,7 +1118,7 @@ std::string GetSchedulerGroupName(pid_t tid) { } void DumpNativeStack(std::ostream& os, pid_t tid, const char* prefix, - mirror::ArtMethod* current_method) { + mirror::ArtMethod* current_method, void* ucontext_ptr) { #if __linux__ // b/18119146 if (RUNNING_ON_VALGRIND != 0) { @@ -1134,7 +1134,7 @@ void DumpNativeStack(std::ostream& os, pid_t tid, const char* prefix, #endif std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid)); - if (!backtrace->Unwind(0)) { + if (!backtrace->Unwind(0, reinterpret_cast<ucontext*>(ucontext_ptr))) { os << prefix << "(backtrace::Unwind failed for thread " << tid << ")\n"; return; } else if (backtrace->NumFrames() == 0) { diff --git a/runtime/utils.h b/runtime/utils.h index f9622b7..b5413e7 100644 --- a/runtime/utils.h +++ b/runtime/utils.h @@ -465,7 +465,7 @@ void SetThreadName(const char* thread_name); // Dumps the native stack for thread 'tid' to 'os'. void DumpNativeStack(std::ostream& os, pid_t tid, const char* prefix = "", - mirror::ArtMethod* current_method = nullptr) + mirror::ArtMethod* current_method = nullptr, void* ucontext = nullptr) NO_THREAD_SAFETY_ANALYSIS; // Dumps the kernel stack for thread 'tid' to 'os'. Note that this is only available on linux-x86. |