summaryrefslogtreecommitdiff
path: root/tests/pthread_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/pthread_test.cpp')
-rw-r--r--tests/pthread_test.cpp58
1 files changed, 52 insertions, 6 deletions
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 9ecb10cbc..f28861231 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -356,9 +356,9 @@ TEST_F(pthread_DeathTest, pthread_bug_37410) {
}
static void* SignalHandlerFn(void* arg) {
- sigset_t wait_set;
- sigfillset(&wait_set);
- return reinterpret_cast<void*>(sigwait(&wait_set, reinterpret_cast<int*>(arg)));
+ sigset64_t wait_set;
+ sigfillset64(&wait_set);
+ return reinterpret_cast<void*>(sigwait64(&wait_set, reinterpret_cast<int*>(arg)));
}
TEST(pthread, pthread_sigmask) {
@@ -402,6 +402,47 @@ TEST(pthread, pthread_sigmask) {
ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &original_set, NULL));
}
+TEST(pthread, pthread_sigmask64_SIGTRMIN) {
+ // Check that SIGRTMIN isn't blocked.
+ sigset64_t original_set;
+ sigemptyset64(&original_set);
+ ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, NULL, &original_set));
+ ASSERT_FALSE(sigismember64(&original_set, SIGRTMIN));
+
+ // Block SIGRTMIN.
+ sigset64_t set;
+ sigemptyset64(&set);
+ sigaddset64(&set, SIGRTMIN);
+ ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, &set, NULL));
+
+ // Check that SIGRTMIN is blocked.
+ sigset64_t final_set;
+ sigemptyset64(&final_set);
+ ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, NULL, &final_set));
+ ASSERT_TRUE(sigismember64(&final_set, SIGRTMIN));
+ // ...and that sigprocmask64 agrees with pthread_sigmask64.
+ sigemptyset64(&final_set);
+ ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, NULL, &final_set));
+ ASSERT_TRUE(sigismember64(&final_set, SIGRTMIN));
+
+ // Spawn a thread that calls sigwait64 and tells us what it received.
+ pthread_t signal_thread;
+ int received_signal = -1;
+ ASSERT_EQ(0, pthread_create(&signal_thread, NULL, SignalHandlerFn, &received_signal));
+
+ // Send that thread SIGRTMIN.
+ pthread_kill(signal_thread, SIGRTMIN);
+
+ // See what it got.
+ void* join_result;
+ ASSERT_EQ(0, pthread_join(signal_thread, &join_result));
+ ASSERT_EQ(SIGRTMIN, received_signal);
+ ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result));
+
+ // Restore the original signal mask.
+ ASSERT_EQ(0, pthread_sigmask64(SIG_SETMASK, &original_set, NULL));
+}
+
static void test_pthread_setname_np__pthread_getname_np(pthread_t t) {
ASSERT_EQ(0, pthread_setname_np(t, "short"));
char name[32];
@@ -1378,18 +1419,23 @@ TEST(pthread, pthread_attr_getstack__main_thread) {
EXPECT_EQ(stack_size, stack_size2);
#if defined(__BIONIC__)
- // What does /proc/self/maps' [stack] line say?
+ // Find stack in /proc/self/maps using a pointer to the stack.
+ //
+ // We do not use "[stack]" label because in native-bridge environment it is not
+ // guaranteed to point to the right stack. A native bridge implementation may
+ // keep separate stack for the guest code.
void* maps_stack_hi = NULL;
std::vector<map_record> maps;
ASSERT_TRUE(Maps::parse_maps(&maps));
+ uintptr_t stack_address = reinterpret_cast<uintptr_t>(&maps_stack_hi);
for (const auto& map : maps) {
- if (map.pathname == "[stack]") {
+ if (map.addr_start <= stack_address && map.addr_end > stack_address){
maps_stack_hi = reinterpret_cast<void*>(map.addr_end);
break;
}
}
- // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size.
+ // The high address of the /proc/self/maps stack region should equal stack_base + stack_size.
// Remember that the stack grows down (and is mapped in on demand), so the low address of the
// region isn't very interesting.
EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size);