From e8b9afcd0cd86b8808af29a97332038aab70c604 Mon Sep 17 00:00:00 2001 From: Dave Allison Date: Wed, 20 Aug 2014 17:38:41 -0700 Subject: [PATCH] Fix fault handler to unregister on shutdown This fixes a problem with the fault handler where it wasn't unregistering itself during shutdown of the runtime. Bug: 17133266 Change-Id: If4758b14ded0fba194897191b1a8d8d7b0b3e6e5 --- runtime/fault_handler.cc | 11 ++++++++++- runtime/fault_handler.h | 2 ++ runtime/runtime.cc | 3 +++ sigchainlib/sigchain.cc | 3 +-- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/runtime/fault_handler.cc b/runtime/fault_handler.cc index 8ddaf5cf2..68fad7ba2 100644 --- a/runtime/fault_handler.cc +++ b/runtime/fault_handler.cc @@ -41,7 +41,7 @@ static void art_fault_handler(int sig, siginfo_t* info, void* context) { fault_manager.HandleFault(sig, info, context); } -FaultManager::FaultManager() { +FaultManager::FaultManager() : initialized_(false) { sigaction(SIGSEGV, nullptr, &oldaction_); } @@ -50,6 +50,7 @@ FaultManager::~FaultManager() { void FaultManager::Init() { + CHECK(!initialized_); struct sigaction action; action.sa_sigaction = art_fault_handler; sigemptyset(&action.sa_mask); @@ -65,6 +66,14 @@ void FaultManager::Init() { } // Make sure our signal handler is called before any user handlers. ClaimSignalChain(SIGSEGV, &oldaction_); + initialized_ = true; +} + +void FaultManager::Shutdown() { + if (initialized_) { + UnclaimSignalChain(SIGSEGV); + initialized_ = false; + } } void FaultManager::HandleFault(int sig, siginfo_t* info, void* context) { diff --git a/runtime/fault_handler.h b/runtime/fault_handler.h index 1acd0247e..0e9b9081e 100644 --- a/runtime/fault_handler.h +++ b/runtime/fault_handler.h @@ -39,6 +39,7 @@ class FaultManager { ~FaultManager(); void Init(); + void Shutdown(); void HandleFault(int sig, siginfo_t* info, void* context); void AddHandler(FaultHandler* handler, bool generated_code); @@ -58,6 +59,7 @@ class FaultManager { std::vector generated_code_handlers_; std::vector other_handlers_; struct sigaction oldaction_; + bool initialized_; DISALLOW_COPY_AND_ASSIGN(FaultManager); }; diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 4bd99436e..5abeac776 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -169,6 +169,9 @@ Runtime::~Runtime() { BackgroundMethodSamplingProfiler::Shutdown(); } + // Shutdown the fault manager if it was initialized. + fault_manager.Shutdown(); + Trace::Shutdown(); // Make sure to let the GC complete if it is running. diff --git a/sigchainlib/sigchain.cc b/sigchainlib/sigchain.cc index 6f9308383..2ba740563 100644 --- a/sigchainlib/sigchain.cc +++ b/sigchainlib/sigchain.cc @@ -45,8 +45,8 @@ class SignalAction { // Unclaim the signal and restore the old action. void Unclaim(int signal) { - claimed_ = false; sigaction(signal, &action_, NULL); // Restore old action. + claimed_ = false; } // Get the action associated with this signal. @@ -164,7 +164,6 @@ int sigaction(int signal, const struct sigaction* new_action, struct sigaction* return linked_sigaction(signal, new_action, old_action); } - int sigprocmask(int how, const sigset_t* bionic_new_set, sigset_t* bionic_old_set) { const sigset_t* new_set_ptr = bionic_new_set; sigset_t tmpset; -- 2.11.0