summaryrefslogtreecommitdiff
path: root/runtime/fault_handler.cc
diff options
context:
space:
mode:
author Dave Allison <dallison@google.com> 2014-05-29 19:54:27 +0000
committer Android Git Automerger <android-git-automerger@android.com> 2014-05-29 19:54:27 +0000
commitac835c68fc3e59144f3aa080ad0dbdd2cbe96968 (patch)
treec9a62a2d842b26f28679c9f2e8a44e86692dd710 /runtime/fault_handler.cc
parentf10e5b162d618e5e6bf78919ebd2d4bc0e2e9f83 (diff)
parent8adc1d9d1dd3fabdde6f1ec1b0c735ea8bcbf8e8 (diff)
am 8adc1d9d: Merge "Make use of sigchainlib for signal chaining for implicit checks"
* commit '8adc1d9d1dd3fabdde6f1ec1b0c735ea8bcbf8e8': Make use of sigchainlib for signal chaining for implicit checks
Diffstat (limited to 'runtime/fault_handler.cc')
-rw-r--r--runtime/fault_handler.cc27
1 files changed, 26 insertions, 1 deletions
diff --git a/runtime/fault_handler.cc b/runtime/fault_handler.cc
index 8d750c5bdd..15c38c1f4b 100644
--- a/runtime/fault_handler.cc
+++ b/runtime/fault_handler.cc
@@ -29,12 +29,22 @@
#include "mirror/object-inl.h"
#include "object_utils.h"
#include "scoped_thread_state_change.h"
+#ifdef HAVE_ANDROID_OS
+#include "sigchain.h"
+#endif
#include "verify_object-inl.h"
namespace art {
// Static fault manger object accessed by signal handler.
FaultManager fault_manager;
+extern "C" {
+void art_sigsegv_fault() {
+ // Set a breakpoint here to be informed when a SIGSEGV is unhandled by ART.
+ VLOG(signals)<< "Caught unknown SIGSEGV in ART fault handler - chaining to next handler.";
+}
+}
+
// Signal handler called on SIGSEGV.
static void art_fault_handler(int sig, siginfo_t* info, void* context) {
fault_manager.HandleFault(sig, info, context);
@@ -45,9 +55,13 @@ FaultManager::FaultManager() {
}
FaultManager::~FaultManager() {
+#ifdef HAVE_ANDROID_OS
+ UnclaimSignalChain(SIGSEGV);
+#endif
sigaction(SIGSEGV, &oldaction_, nullptr); // Restore old handler.
}
+
void FaultManager::Init() {
struct sigaction action;
action.sa_sigaction = art_fault_handler;
@@ -56,7 +70,13 @@ void FaultManager::Init() {
#if !defined(__mips__)
action.sa_restorer = nullptr;
#endif
+
+ // Set our signal handler now.
sigaction(SIGSEGV, &action, &oldaction_);
+#ifdef HAVE_ANDROID_OS
+ // Make sure our signal handler is called before any user handlers.
+ ClaimSignalChain(SIGSEGV, &oldaction_);
+#endif
}
void FaultManager::HandleFault(int sig, siginfo_t* info, void* context) {
@@ -79,8 +99,13 @@ void FaultManager::HandleFault(int sig, siginfo_t* info, void* context) {
return;
}
}
- VLOG(signals)<< "Caught unknown SIGSEGV in ART fault handler";
+ art_sigsegv_fault();
+
+#ifdef HAVE_ANDROID_OS
+ InvokeUserSignalHandler(sig, info, context);
+#else
oldaction_.sa_sigaction(sig, info, context);
+#endif
}
void FaultManager::AddHandler(FaultHandler* handler, bool generated_code) {