summaryrefslogtreecommitdiffstats
path: root/sigchainlib
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-10-15 16:59:47 -0700
committerMathieu Chartier <mathieuc@google.com>2014-10-16 19:16:41 -0700
commitd000480134b7b00895fbfd142f1d1e18d9cfa6e9 (patch)
treea9fab808555310308aecda2a59a7c90727ede0ff /sigchainlib
parentd866c7616cb3426c431b635ae69964ce69c2ecb5 (diff)
downloadart-d000480134b7b00895fbfd142f1d1e18d9cfa6e9.zip
art-d000480134b7b00895fbfd142f1d1e18d9cfa6e9.tar.gz
art-d000480134b7b00895fbfd142f1d1e18d9cfa6e9.tar.bz2
Add way to ensure we are at the front of the sigaction chain
Calling this after jni_on_load fixes the unity apps. This is not exactly correct since we may already have the following chain. Start up: Us -> debuggerd After app goes in front: App -> us -> debuggerd After we put ourself back at the front: Us -> app -> us -> app -> .... stack overflow. Bug: 17620677 Change-Id: I9183997e3d5ebd51c320b5d51425be5142e938f3 (cherry picked from commit 1f24296c7c8a6501ee2388c0d20b48f471b48660)
Diffstat (limited to 'sigchainlib')
-rw-r--r--sigchainlib/sigchain.cc22
-rw-r--r--sigchainlib/sigchain.h6
-rw-r--r--sigchainlib/sigchain_dummy.cc5
-rw-r--r--sigchainlib/version-script.txt1
4 files changed, 30 insertions, 4 deletions
diff --git a/sigchainlib/sigchain.cc b/sigchainlib/sigchain.cc
index c5015e8..601e321 100644
--- a/sigchainlib/sigchain.cc
+++ b/sigchainlib/sigchain.cc
@@ -35,6 +35,8 @@
namespace art {
+typedef int (*SigActionFnPtr)(int, const struct sigaction*, struct sigaction*);
+
class SignalAction {
public:
SignalAction() : claimed_(false), uses_old_style_(false) {
@@ -147,7 +149,20 @@ extern "C" void InvokeUserSignalHandler(int sig, siginfo_t* info, void* context)
}
}
-// These functions are C linkage since they replace the functions in libc.
+extern "C" void EnsureFrontOfChain(int signal, struct sigaction* expected_action) {
+ CheckSignalValid(signal);
+ // Read the current action without looking at the chain, it should be the expected action.
+ SigActionFnPtr linked_sigaction = reinterpret_cast<SigActionFnPtr>(linked_sigaction_sym);
+ struct sigaction current_action;
+ linked_sigaction(signal, nullptr, &current_action);
+ // If the sigactions don't match then we put the current action on the chain and make ourself as
+ // the main action.
+ if (current_action.sa_sigaction != expected_action->sa_sigaction) {
+ log("Warning: Unexpected sigaction action found %p\n", current_action.sa_sigaction);
+ user_sigactions[signal].Claim(current_action);
+ linked_sigaction(signal, expected_action, nullptr);
+ }
+}
extern "C" int sigaction(int signal, const struct sigaction* new_action, struct sigaction* old_action) {
// If this signal has been claimed as a signal chain, record the user's
@@ -179,9 +194,7 @@ extern "C" int sigaction(int signal, const struct sigaction* new_action, struct
log("Unable to find next sigaction in signal chain");
abort();
}
-
- typedef int (*SigAction)(int, const struct sigaction*, struct sigaction*);
- SigAction linked_sigaction = reinterpret_cast<SigAction>(linked_sigaction_sym);
+ SigActionFnPtr linked_sigaction = reinterpret_cast<SigActionFnPtr>(linked_sigaction_sym);
return linked_sigaction(signal, new_action, old_action);
}
@@ -287,5 +300,6 @@ extern "C" void InitializeSignalChain() {
}
initialized = true;
}
+
} // namespace art
diff --git a/sigchainlib/sigchain.h b/sigchainlib/sigchain.h
index 0de0d08..79b76a7 100644
--- a/sigchainlib/sigchain.h
+++ b/sigchainlib/sigchain.h
@@ -19,6 +19,8 @@
#include <signal.h>
+namespace art {
+
extern "C" void InitializeSignalChain();
extern "C" void ClaimSignalChain(int signal, struct sigaction* oldaction);
@@ -27,4 +29,8 @@ extern "C" void UnclaimSignalChain(int signal);
extern "C" void InvokeUserSignalHandler(int sig, siginfo_t* info, void* context);
+extern "C" void EnsureFrontOfChain(int signal, struct sigaction* expected_action);
+
+} // namespace art
+
#endif // ART_SIGCHAINLIB_SIGCHAIN_H_
diff --git a/sigchainlib/sigchain_dummy.cc b/sigchainlib/sigchain_dummy.cc
index 7176f05..fbc8c3f 100644
--- a/sigchainlib/sigchain_dummy.cc
+++ b/sigchainlib/sigchain_dummy.cc
@@ -57,3 +57,8 @@ extern "C" void InitializeSignalChain() {
log("InitializeSignalChain is not exported by the main executable.");
abort();
}
+
+extern "C" void EnsureFrontOfChain(int signal, struct sigaction* expected_action) {
+ log("EnsureFrontOfChain is not exported by the main executable.");
+ abort();
+}
diff --git a/sigchainlib/version-script.txt b/sigchainlib/version-script.txt
index 8030da4..ce15054 100644
--- a/sigchainlib/version-script.txt
+++ b/sigchainlib/version-script.txt
@@ -4,6 +4,7 @@ global:
UnclaimSignalChain;
InvokeUserSignalHandler;
InitializeSignalChain;
+ EnsureFrontOfChain;
sigaction;
signal;
sigprocmask;