Fix sigsetjmp/siglongjmp to save/restore RT signals on arm/x86 too.
Our arm and x86 ABIs shipped with a 32-bit `sigset_t`, so we need to
use sigprocmask64 to save/restore the RT signals too. (This is important
because several are in use by the system, and the behavior of our 32-bit
`sigset_t` is to clear the RT signals.)
Bug: http://b/72493232
Test: ran tests
Change-Id: Idff91f8b2849276e5a3073d07eccd84e02a34410
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index bb01601..4f5e60c 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -19,6 +19,8 @@
#include <setjmp.h>
#include <stdlib.h>
+#include "ScopedSignalHandler.h"
+
TEST(setjmp, setjmp_smoke) {
int value;
jmp_buf jb;
@@ -63,61 +65,59 @@
}
}
-// Two distinct signal sets, pipu
+// Two distinct signal sets.
struct SigSets {
SigSets() : one(MakeSigSet(0)), two(MakeSigSet(1)) {
}
- static sigset_t MakeSigSet(int offset) {
- sigset_t ss;
- sigemptyset(&ss);
- sigaddset(&ss, SIGUSR1 + offset);
-#if defined(__LP64__)
- // For arm and x86, sigset_t was too small for the RT signals.
- // For mips, sigset_t was large enough but jmp_buf wasn't.
- sigaddset(&ss, SIGRTMIN + offset);
-#endif
+ static sigset64_t MakeSigSet(int offset) {
+ sigset64_t ss;
+ sigemptyset64(&ss);
+ sigaddset64(&ss, SIGUSR1 + offset);
+ sigaddset64(&ss, SIGRTMIN + offset);
return ss;
}
- sigset_t one;
- sigset_t two;
- sigset_t original;
+ sigset64_t one;
+ sigset64_t two;
};
-void AssertSigmaskEquals(const sigset_t& expected) {
- sigset_t actual;
- sigprocmask(0 /* ignored */, NULL, &actual);
- size_t end = sizeof(sigset_t) * 8;
+void AssertSigmaskEquals(const sigset64_t& expected) {
+ sigset64_t actual;
+ sigprocmask64(SIG_SETMASK, NULL, &actual);
+ size_t end = sizeof(expected) * 8;
for (size_t i = 1; i <= end; ++i) {
- EXPECT_EQ(sigismember(&expected, i), sigismember(&actual, i)) << i;
+ EXPECT_EQ(sigismember64(&expected, i), sigismember64(&actual, i)) << i;
}
}
TEST(setjmp, _setjmp_signal_mask) {
+ SignalMaskRestorer smr;
+
// _setjmp/_longjmp do not save/restore the signal mask.
SigSets ss;
- sigprocmask(SIG_SETMASK, &ss.one, &ss.original);
+ sigprocmask64(SIG_SETMASK, &ss.one, nullptr);
jmp_buf jb;
if (_setjmp(jb) == 0) {
- sigprocmask(SIG_SETMASK, &ss.two, NULL);
+ sigprocmask64(SIG_SETMASK, &ss.two, NULL);
_longjmp(jb, 1);
FAIL(); // Unreachable.
} else {
AssertSigmaskEquals(ss.two);
}
- sigprocmask(SIG_SETMASK, &ss.original, NULL);
}
TEST(setjmp, setjmp_signal_mask) {
+ SignalMaskRestorer smr;
+
// setjmp/longjmp do save/restore the signal mask on bionic, but not on glibc.
// This is a BSD versus System V historical accident. POSIX leaves the
// behavior unspecified, so any code that cares needs to use sigsetjmp.
SigSets ss;
- sigprocmask(SIG_SETMASK, &ss.one, &ss.original);
+ sigprocmask64(SIG_SETMASK, &ss.one, nullptr);
jmp_buf jb;
if (setjmp(jb) == 0) {
- sigprocmask(SIG_SETMASK, &ss.two, NULL);
+ sigprocmask64(SIG_SETMASK, &ss.two, NULL);
longjmp(jb, 1);
FAIL(); // Unreachable.
} else {
@@ -129,37 +129,38 @@
AssertSigmaskEquals(ss.two);
#endif
}
- sigprocmask(SIG_SETMASK, &ss.original, NULL);
}
TEST(setjmp, sigsetjmp_0_signal_mask) {
+ SignalMaskRestorer smr;
+
// sigsetjmp(0)/siglongjmp do not save/restore the signal mask.
SigSets ss;
- sigprocmask(SIG_SETMASK, &ss.one, &ss.original);
+ sigprocmask64(SIG_SETMASK, &ss.one, nullptr);
sigjmp_buf sjb;
if (sigsetjmp(sjb, 0) == 0) {
- sigprocmask(SIG_SETMASK, &ss.two, NULL);
+ sigprocmask64(SIG_SETMASK, &ss.two, NULL);
siglongjmp(sjb, 1);
FAIL(); // Unreachable.
} else {
AssertSigmaskEquals(ss.two);
}
- sigprocmask(SIG_SETMASK, &ss.original, NULL);
}
TEST(setjmp, sigsetjmp_1_signal_mask) {
+ SignalMaskRestorer smr;
+
// sigsetjmp(1)/siglongjmp does save/restore the signal mask.
SigSets ss;
- sigprocmask(SIG_SETMASK, &ss.one, &ss.original);
+ sigprocmask64(SIG_SETMASK, &ss.one, nullptr);
sigjmp_buf sjb;
if (sigsetjmp(sjb, 1) == 0) {
- sigprocmask(SIG_SETMASK, &ss.two, NULL);
+ sigprocmask64(SIG_SETMASK, &ss.two, NULL);
siglongjmp(sjb, 1);
FAIL(); // Unreachable.
} else {
AssertSigmaskEquals(ss.one);
}
- sigprocmask(SIG_SETMASK, &ss.original, NULL);
}
#if defined(__aarch64__)
@@ -218,7 +219,7 @@
#elif defined(__aarch64__)
#define __JB_SIGFLAG 0
#elif defined(__i386__)
-#define __JB_SIGFLAG 7
+#define __JB_SIGFLAG 8
#elif defined(__x86_64)
#define __JB_SIGFLAG 8
#elif defined(__mips__) && defined(__LP64__)