dynamic libc: ignore ART profiling signal by default.

These solves the issue that targetting non-profilable apps crashed them.
There is still a race condition between starting the app and the SIG_IGN
being installed, but that will be fixed in follow-ups.

This also does not cover programs that statically link libc, but those are
rare.

This might be reverted if we find a more general solution to
b/151835887.

Bug: 151328035
Test: java profile sysui, doesn't crash
Test: atest CtsBionicTestCases

This is a cherry-pick of 96272df35cbc89c696dcacc0796519a89d9e2212

Change-Id: I6b99352ed50afe15a609f7ddb85312c2676ddf11
Merged-In: I6b99352ed50afe15a609f7ddb85312c2676ddf11
diff --git a/libc/bionic/android_profiling_dynamic.cpp b/libc/bionic/android_profiling_dynamic.cpp
index 54f896c..9d92a6d 100644
--- a/libc/bionic/android_profiling_dynamic.cpp
+++ b/libc/bionic/android_profiling_dynamic.cpp
@@ -63,6 +63,14 @@
   action.sa_flags = SA_SIGINFO | SA_RESTART;
   action.sa_sigaction = HandleProfilingSignal;
   sigaction(BIONIC_SIGNAL_PROFILER, &action, nullptr);
+
+  // The perfetto_hprof ART plugin installs a signal handler to handle this signal. That plugin
+  // does not get loaded for a) non-apps, b) non-profilable apps on user. The default signal
+  // disposition is to crash. We do not want the target to crash if we accidentally target a
+  // non-app or non-profilable process.
+  //
+  // This does *not* get run for processes that statically link libc, and those will still crash.
+  signal(BIONIC_SIGNAL_ART_PROFILER, SIG_IGN);
 }
 
 static void HandleSigsysSeccompOverride(int, siginfo_t*, void*);
diff --git a/libc/platform/bionic/reserved_signals.h b/libc/platform/bionic/reserved_signals.h
index 3c5bc02..c90fc06 100644
--- a/libc/platform/bionic/reserved_signals.h
+++ b/libc/platform/bionic/reserved_signals.h
@@ -47,8 +47,10 @@
 // If you change this, also change __ndk_legacy___libc_current_sigrtmin
 // in <android/legacy_signal_inlines.h> to match.
 
+#define BIONIC_SIGNAL_POSIX_TIMERS (__SIGRTMIN + 0)
 #define BIONIC_SIGNAL_DEBUGGER (__SIGRTMIN + 3)
 #define BIONIC_SIGNAL_PROFILER (__SIGRTMIN + 4)
+#define BIONIC_SIGNAL_ART_PROFILER (__SIGRTMIN + 6)
 #define BIONIC_SIGNAL_FDTRACK (__SIGRTMIN + 7)
 
 #define __SIGRT_RESERVED 8
diff --git a/tests/spawn_test.cpp b/tests/spawn_test.cpp
index 04b66d3..d7ed970 100644
--- a/tests/spawn_test.cpp
+++ b/tests/spawn_test.cpp
@@ -31,6 +31,8 @@
 # if !defined(POSIX_SPAWN_SETSID)
 #  define POSIX_SPAWN_SETSID 0
 # endif
+#else
+#include <platform/bionic/reserved_signals.h>
 #endif
 
 TEST(spawn, posix_spawnattr_init_posix_spawnattr_destroy) {
@@ -292,7 +294,7 @@
   pid_t sid;
 };
 
-static void GetChildStat(posix_spawnattr_t* sa, ProcStat* ps) {
+static __attribute__((unused)) void GetChildStat(posix_spawnattr_t* sa, ProcStat* ps) {
   std::string content;
   CatFileToString(sa, "/proc/self/stat", &content);
 
@@ -307,7 +309,7 @@
   uint64_t sigign;
 };
 
-static void GetChildStatus(posix_spawnattr_t* sa, ProcStatus* ps) {
+static void __attribute__((unused)) GetChildStatus(posix_spawnattr_t* sa, ProcStatus* ps) {
   std::string content;
   CatFileToString(sa, "/proc/self/status", &content);
 
@@ -377,6 +379,9 @@
 }
 
 TEST(spawn, posix_spawn_POSIX_SPAWN_SETSIGMASK) {
+#if defined(__GLIBC__)
+  GTEST_SKIP() << "glibc doesn't ignore the same signals.";
+#else
   // Block SIGBUS in the parent...
   sigset_t just_SIGBUS;
   sigemptyset(&just_SIGBUS);
@@ -400,15 +405,21 @@
   // TIMER_SIGNAL should also be blocked.
   uint64_t expected_blocked = 0;
   SignalSetAdd(&expected_blocked, SIGALRM);
-  SignalSetAdd(&expected_blocked, __SIGRTMIN + 0);
+  SignalSetAdd(&expected_blocked, BIONIC_SIGNAL_POSIX_TIMERS);
   EXPECT_EQ(expected_blocked, ps.sigblk);
 
-  EXPECT_EQ(static_cast<uint64_t>(0), ps.sigign);
+  uint64_t expected_ignored = 0;
+  SignalSetAdd(&expected_ignored, BIONIC_SIGNAL_ART_PROFILER);
+  EXPECT_EQ(expected_ignored, ps.sigign);
 
   ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+#endif
 }
 
 TEST(spawn, posix_spawn_POSIX_SPAWN_SETSIGDEF) {
+#if defined(__GLIBC__)
+  GTEST_SKIP() << "glibc doesn't ignore the same signals.";
+#else
   // Ignore SIGALRM and SIGCONT in the parent...
   ASSERT_NE(SIG_ERR, signal(SIGALRM, SIG_IGN));
   ASSERT_NE(SIG_ERR, signal(SIGCONT, SIG_IGN));
@@ -430,14 +441,16 @@
 
   // TIMER_SIGNAL should be blocked.
   uint64_t expected_blocked = 0;
-  SignalSetAdd(&expected_blocked, __SIGRTMIN + 0);
+  SignalSetAdd(&expected_blocked, BIONIC_SIGNAL_POSIX_TIMERS);
   EXPECT_EQ(expected_blocked, ps.sigblk);
 
   uint64_t expected_ignored = 0;
   SignalSetAdd(&expected_ignored, SIGCONT);
+  SignalSetAdd(&expected_ignored, BIONIC_SIGNAL_ART_PROFILER);
   EXPECT_EQ(expected_ignored, ps.sigign);
 
   ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+#endif
 }
 
 TEST(spawn, signal_stress) {