[RUNTIME] Ignore signal registration for debugging

It's difficult to identify native crash/error of 3rd party app.
Because they can control their app with own signal handling.
Therefore I would like to support the way to ignore signal
registration in 3rd party app with the specific property.

To enable this, do just setprop "debug.ignoreappsignalhandler 1".

Test: test app to hook signal, then setprop debug.ignoreappsignalhandler 1

Change-Id: I56e2f1255a71abae339396379deb8cb5c31c25c5
Merged-In: I56e2f1255a71abae339396379deb8cb5c31c25c5
Signed-off-by: randy.jeong <randy.jeong@samsung.com>
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index de28c28..7de6e1d 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -150,6 +150,7 @@
                                      | (1 << 13),
   PROFILE_SYSTEM_SERVER              = 1 << 14,
   USE_APP_IMAGE_STARTUP_CACHE        = 1 << 16,
+  DEBUG_IGNORE_APP_SIGNAL_HANDLER    = 1 << 17,
 
   // bits to shift (flags & HIDDEN_API_ENFORCEMENT_POLICY_MASK) by to get a value
   // corresponding to hiddenapi::EnforcementPolicy
@@ -235,6 +236,11 @@
     runtime_flags &= ~DEBUG_GENERATE_DEBUG_INFO;
   }
 
+  if ((runtime_flags & DEBUG_IGNORE_APP_SIGNAL_HANDLER) != 0) {
+    runtime->SetSignalHookDebuggable(true);
+    runtime_flags &= ~DEBUG_IGNORE_APP_SIGNAL_HANDLER;
+  }
+
   return runtime_flags;
 }
 
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 4c16e05..fe64b8c 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -2921,4 +2921,8 @@
   return startup_completed_.load(std::memory_order_seq_cst);
 }
 
+void Runtime::SetSignalHookDebuggable(bool value) {
+  SkipAddSignalHandler(value);
+}
+
 }  // namespace art
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 53e669c..0b880c9 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -692,6 +692,8 @@
     is_native_debuggable_ = value;
   }
 
+  void SetSignalHookDebuggable(bool value);
+
   bool AreNonStandardExitsEnabled() const {
     return non_standard_exits_enabled_;
   }
diff --git a/sigchainlib/sigchain.cc b/sigchainlib/sigchain.cc
index 08ee690..ad54f23 100644
--- a/sigchainlib/sigchain.cc
+++ b/sigchainlib/sigchain.cc
@@ -271,6 +271,8 @@
 // Leave an empty element at index 0 for convenience.
 static SignalChain chains[_NSIG + 1];
 
+static bool is_signal_hook_debuggable = false;
+
 void SignalChain::Handler(int signo, siginfo_t* siginfo, void* ucontext_raw) {
   // Try the special handlers first.
   // If one of them crashes, we'll reenter this handler and pass that crash onto the user handler.
@@ -339,6 +341,10 @@
                        SigactionType* old_action,
                        int (*linked)(int, const SigactionType*,
                                      SigactionType*)) {
+  if (is_signal_hook_debuggable) {
+    return 0;
+  }
+
   // If this signal has been claimed as a signal chain, record the user's
   // action but don't pass it on to the kernel.
   // Note that we check that the signal number is in range here.  An out of range signal
@@ -506,5 +512,9 @@
   }
 }
 
+extern "C" void SkipAddSignalHandler(bool value) {
+  is_signal_hook_debuggable = value;
+}
+
 }   // namespace art
 
diff --git a/sigchainlib/sigchain.h b/sigchainlib/sigchain.h
index 23fba03..9c24a6f 100644
--- a/sigchainlib/sigchain.h
+++ b/sigchainlib/sigchain.h
@@ -35,6 +35,7 @@
 extern "C" void RemoveSpecialSignalHandlerFn(int signal, bool (*fn)(int, siginfo_t*, void*));
 
 extern "C" void EnsureFrontOfChain(int signal);
+extern "C" void SkipAddSignalHandler(bool value);
 
 }  // namespace art
 
diff --git a/sigchainlib/sigchain_dummy.cc b/sigchainlib/sigchain_dummy.cc
index c274530..db72b58 100644
--- a/sigchainlib/sigchain_dummy.cc
+++ b/sigchainlib/sigchain_dummy.cc
@@ -46,6 +46,11 @@
   abort();
 }
 
+extern "C" void SkipAddSignalHandler(bool value ATTRIBUTE_UNUSED) {
+  log("SkipAddSignalHandler is not exported by the main executable.");
+  abort();
+}
+
 #pragma GCC diagnostic pop
 
 }  // namespace art
diff --git a/sigchainlib/version-script32.txt b/sigchainlib/version-script32.txt
index e8a18e7..70810e0 100644
--- a/sigchainlib/version-script32.txt
+++ b/sigchainlib/version-script32.txt
@@ -3,6 +3,7 @@
   EnsureFrontOfChain;
   AddSpecialSignalHandlerFn;
   RemoveSpecialSignalHandlerFn;
+  SkipAddSignalHandler;
   bsd_signal;
   sigaction;
   sigaction64;
diff --git a/sigchainlib/version-script64.txt b/sigchainlib/version-script64.txt
index 72c86a1..7bcd76b 100644
--- a/sigchainlib/version-script64.txt
+++ b/sigchainlib/version-script64.txt
@@ -3,6 +3,7 @@
   EnsureFrontOfChain;
   AddSpecialSignalHandlerFn;
   RemoveSpecialSignalHandlerFn;
+  SkipAddSignalHandler;
   sigaction;
   sigaction64;
   signal;