diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-10-15 16:59:47 -0700 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2014-10-16 19:16:41 -0700 |
commit | d000480134b7b00895fbfd142f1d1e18d9cfa6e9 (patch) | |
tree | a9fab808555310308aecda2a59a7c90727ede0ff /sigchainlib | |
parent | d866c7616cb3426c431b635ae69964ce69c2ecb5 (diff) | |
download | art-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.cc | 22 | ||||
-rw-r--r-- | sigchainlib/sigchain.h | 6 | ||||
-rw-r--r-- | sigchainlib/sigchain_dummy.cc | 5 | ||||
-rw-r--r-- | sigchainlib/version-script.txt | 1 |
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, ¤t_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; |