Better handling of sigset_t on LP32.

The main motivation here is that the sigprocmask in pthread_exit wasn't
actually blocking the real-time signals, and debuggerd (amongst other
things) is using them. I wasn't able to write a test that actually won
that race but I did write an equivalent one for posix_spawn.

This also fixes all the uses of sigset_t where the sigset_t isn't
exposed to the outside (which we can't easily fix because it would be
an ABI change).

Bug: https://issuetracker.google.com/72291624
Test: ran tests
Change-Id: Ib6eebebc5a7b0150079f1cb79593247917dcf750
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 207c156..5cbec88 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -464,33 +464,45 @@
   ASSERT_EQ(EINVAL, errno);
 }
 
-TEST(signal, sighold_sigpause_sigrelse) {
-  static int sigalrm_handler_call_count;
-  auto sigalrm_handler = [](int) { sigalrm_handler_call_count++; };
-  ScopedSignalHandler sigalrm{SIGALRM, sigalrm_handler};
-  ScopedSignalMask mask;
+static void TestSigholdSigpauseSigrelse(int sig) {
+  static int signal_handler_call_count = 0;
+  ScopedSignalHandler ssh{sig, [](int) { signal_handler_call_count++; }};
+  SignalMaskRestorer mask_restorer;
   sigset_t set;
 
-  // sighold(SIGALRM) should add SIGALRM to the signal mask ...
-  ASSERT_EQ(0, sighold(SIGALRM));
+  // sighold(SIGALRM/SIGRTMIN) should add SIGALRM/SIGRTMIN to the signal mask ...
+  ASSERT_EQ(0, sighold(sig));
   ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
-  EXPECT_TRUE(sigismember(&set, SIGALRM));
+  EXPECT_TRUE(sigismember(&set, sig));
 
-  // ... preventing our SIGALRM handler from running ...
-  raise(SIGALRM);
-  ASSERT_EQ(0, sigalrm_handler_call_count);
-  // ... until sigpause(SIGALRM) temporarily unblocks it.
-  ASSERT_EQ(-1, sigpause(SIGALRM));
+  // ... preventing our SIGALRM/SIGRTMIN handler from running ...
+  raise(sig);
+  ASSERT_EQ(0, signal_handler_call_count);
+  // ... until sigpause(SIGALRM/SIGRTMIN) temporarily unblocks it.
+  ASSERT_EQ(-1, sigpause(sig));
   ASSERT_EQ(EINTR, errno);
-  ASSERT_EQ(1, sigalrm_handler_call_count);
+  ASSERT_EQ(1, signal_handler_call_count);
 
-  // But sigpause(SIGALRM) shouldn't permanently unblock SIGALRM.
-  ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
-  EXPECT_TRUE(sigismember(&set, SIGALRM));
+  if (sig >= SIGRTMIN && sizeof(void*) == 8) {
+    // But sigpause(SIGALRM/SIGRTMIN) shouldn't permanently unblock SIGALRM/SIGRTMIN.
+    ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
+    EXPECT_TRUE(sigismember(&set, sig));
 
-  ASSERT_EQ(0, sigrelse(SIGALRM));
-  ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
-  EXPECT_FALSE(sigismember(&set, SIGALRM));
+    // Whereas sigrelse(SIGALRM/SIGRTMIN) should.
+    ASSERT_EQ(0, sigrelse(sig));
+    ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
+    EXPECT_FALSE(sigismember(&set, sig));
+  } else {
+    // sigismember won't work for SIGRTMIN on LP32.
+  }
+}
+
+TEST(signal, sighold_sigpause_sigrelse) {
+  TestSigholdSigpauseSigrelse(SIGALRM);
+}
+
+TEST(signal, sighold_sigpause_sigrelse_RT) {
+  TestSigholdSigpauseSigrelse(SIGRTMIN);
 }
 
 TEST(signal, sigset_EINVAL) {
@@ -499,23 +511,48 @@
   ASSERT_EQ(EINVAL, errno);
 }
 
-TEST(signal, sigset) {
-  auto sigalrm_handler = [](int) { };
-  ScopedSignalHandler sigalrm{SIGALRM, sigalrm_handler};
-  ScopedSignalMask mask;
+TEST(signal, sigset_RT) {
+  static int signal_handler_call_count = 0;
+  auto signal_handler = [](int) { signal_handler_call_count++; };
+  ScopedSignalHandler ssh{SIGRTMIN, signal_handler};
+  SignalMaskRestorer mask_restorer;
 
-  // block SIGALRM so the next sigset(SIGARLM) call will return SIG_HOLD
-  sigset_t sigalrm_set;
-  sigemptyset(&sigalrm_set);
-  sigaddset(&sigalrm_set, SIGALRM);
-  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &sigalrm_set, nullptr));
-
+  ASSERT_EQ(signal_handler, sigset(SIGRTMIN, SIG_HOLD));
+#if defined(__LP64__)
   sigset_t set;
-  ASSERT_EQ(SIG_HOLD, sigset(SIGALRM, sigalrm_handler));
+  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, nullptr, &set));
+  ASSERT_TRUE(sigismember(&set, SIGRTMIN));
+#endif
+
+  ASSERT_EQ(SIG_HOLD, sigset(SIGRTMIN, signal_handler));
+  ASSERT_EQ(signal_handler, sigset(SIGRTMIN, signal_handler));
+  ASSERT_EQ(0, signal_handler_call_count);
+  raise(SIGRTMIN);
+  ASSERT_EQ(1, signal_handler_call_count);
+}
+
+TEST(signal, sigset) {
+  static int signal_handler_call_count = 0;
+  auto signal_handler = [](int) { signal_handler_call_count++; };
+  ScopedSignalHandler ssh{SIGALRM, signal_handler};
+  SignalMaskRestorer mask_restorer;
+
+  ASSERT_EQ(0, signal_handler_call_count);
+  raise(SIGALRM);
+  ASSERT_EQ(1, signal_handler_call_count);
+
+  // Block SIGALRM so the next sigset(SIGARLM) call will return SIG_HOLD.
+  sigset_t set;
+  sigemptyset(&set);
+  sigaddset(&set, SIGALRM);
+  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &set, nullptr));
+
+  sigemptyset(&set);
+  ASSERT_EQ(SIG_HOLD, sigset(SIGALRM, signal_handler));
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, nullptr, &set));
   EXPECT_FALSE(sigismember(&set, SIGALRM));
 
-  ASSERT_EQ(sigalrm_handler, sigset(SIGALRM, SIG_IGN));
+  ASSERT_EQ(signal_handler, sigset(SIGALRM, SIG_IGN));
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, nullptr, &set));
   EXPECT_FALSE(sigismember(&set, SIGALRM));