summaryrefslogtreecommitdiffstats
path: root/sigchainlib
diff options
context:
space:
mode:
authorDave Allison <dallison@google.com>2014-08-26 11:07:58 -0700
committerDave Allison <dallison@google.com>2014-08-27 12:47:44 -0700
commit8ce6b9040747054b444a7fa706503cd257801936 (patch)
tree04712170addb252d307ef9015abfc9bfc2b73581 /sigchainlib
parenta0a0da29e7d4d5c1bd471c49f1a4b6ec98fb767a (diff)
downloadart-8ce6b9040747054b444a7fa706503cd257801936.zip
art-8ce6b9040747054b444a7fa706503cd257801936.tar.gz
art-8ce6b9040747054b444a7fa706503cd257801936.tar.bz2
Handle nested signals
This allows for signals to be raised inside the ART signal handler. This can occur when the JavaStackTraceHandler attempts to generate a stack trace and something goes wrong. It also fixes an issue where the fault manager was not being correctly shut down inside the signal chaining code. In this case the signal handler was not restored to the original. Bug: 17006816 Bug: 17133266 (cherry picked from commit fabe91e0d558936ac26b98d2b4ee1af08f58831d) Change-Id: I10730ef52d5d8d34610a5293253b3be6caf4829e
Diffstat (limited to 'sigchainlib')
-rw-r--r--sigchainlib/sigchain.cc18
1 files changed, 13 insertions, 5 deletions
diff --git a/sigchainlib/sigchain.cc b/sigchainlib/sigchain.cc
index 2ba7405..c655226 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) {
- sigaction(signal, &action_, NULL); // Restore old action.
claimed_ = false;
+ sigaction(signal, &action_, NULL); // Restore old action.
}
// Get the action associated with this signal.
@@ -155,8 +155,12 @@ int sigaction(int signal, const struct sigaction* new_action, struct sigaction*
void* linked_sigaction_sym = dlsym(RTLD_NEXT, "sigaction");
if (linked_sigaction_sym == nullptr) {
- log("Unable to find next sigaction in signal chain");
- abort();
+ linked_sigaction_sym = dlsym(RTLD_DEFAULT, "sigaction");
+ if (linked_sigaction_sym == nullptr ||
+ linked_sigaction_sym == reinterpret_cast<void*>(sigaction)) {
+ log("Unable to find next sigaction in signal chain");
+ abort();
+ }
}
typedef int (*SigAction)(int, const struct sigaction*, struct sigaction*);
@@ -184,8 +188,12 @@ int sigprocmask(int how, const sigset_t* bionic_new_set, sigset_t* bionic_old_se
void* linked_sigprocmask_sym = dlsym(RTLD_NEXT, "sigprocmask");
if (linked_sigprocmask_sym == nullptr) {
- log("Unable to find next sigprocmask in signal chain");
- abort();
+ linked_sigprocmask_sym = dlsym(RTLD_DEFAULT, "sigprocmask");
+ if (linked_sigprocmask_sym == nullptr ||
+ linked_sigprocmask_sym == reinterpret_cast<void*>(sigprocmask)) {
+ log("Unable to find next sigprocmask in signal chain");
+ abort();
+ }
}
typedef int (*SigProcMask)(int how, const sigset_t*, sigset_t*);