1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <signal.h> 18 19#include <gtest/gtest.h> 20 21#include <errno.h> 22 23#include "ScopedSignalHandler.h" 24 25static size_t SIGNAL_MIN() { 26 return 1; // Signals start at 1 (SIGHUP), not 0. 27} 28 29static size_t SIGNAL_MAX() { 30 size_t result = SIGRTMAX; 31 32#if defined(__BIONIC__) && !defined(__mips__) && !defined(__LP64__) 33 // 32-bit bionic's sigset_t is too small for ARM and x86: 32 bits instead of 64. 34 // This means you can't refer to any of the real-time signals. 35 // See http://b/3038348 and http://b/5828899. 36 result = 32; 37#else 38 // Otherwise, C libraries should be perfectly capable of using their largest signal. 39 if (sizeof(sigset_t) * 8 < static_cast<size_t>(SIGRTMAX)) { 40 abort(); 41 } 42#endif 43 44 return result; 45} 46 47template <typename Fn> 48static void TestSigSet1(Fn fn) { 49 // NULL sigset_t*. 50 sigset_t* set_ptr = NULL; 51 errno = 0; 52 ASSERT_EQ(-1, fn(set_ptr)); 53 ASSERT_EQ(EINVAL, errno); 54 55 // Non-NULL. 56 sigset_t set; 57 errno = 0; 58 ASSERT_EQ(0, fn(&set)); 59 ASSERT_EQ(0, errno); 60} 61 62template <typename Fn> 63static void TestSigSet2(Fn fn) { 64 // NULL sigset_t*. 65 sigset_t* set_ptr = NULL; 66 errno = 0; 67 ASSERT_EQ(-1, fn(set_ptr, SIGSEGV)); 68 ASSERT_EQ(EINVAL, errno); 69 70 sigset_t set; 71 sigemptyset(&set); 72 73 // Bad signal number: too small. 74 errno = 0; 75 ASSERT_EQ(-1, fn(&set, 0)); 76 ASSERT_EQ(EINVAL, errno); 77 78 // Bad signal number: too high. 79 errno = 0; 80 ASSERT_EQ(-1, fn(&set, SIGNAL_MAX() + 1)); 81 ASSERT_EQ(EINVAL, errno); 82 83 // Good signal numbers, low and high ends of range. 84 errno = 0; 85 ASSERT_EQ(0, fn(&set, SIGNAL_MIN())); 86 ASSERT_EQ(0, errno); 87 ASSERT_EQ(0, fn(&set, SIGNAL_MAX())); 88 ASSERT_EQ(0, errno); 89} 90 91TEST(signal, sigismember_invalid) { 92 TestSigSet2(sigismember); 93} 94 95TEST(signal, sigaddset_invalid) { 96 TestSigSet2(sigaddset); 97} 98 99TEST(signal, sigdelset_invalid) { 100 TestSigSet2(sigdelset); 101} 102 103TEST(signal, sigemptyset_invalid) { 104 TestSigSet1(sigemptyset); 105} 106 107TEST(signal, sigfillset_invalid) { 108 TestSigSet1(sigfillset); 109} 110 111TEST(signal, raise_invalid) { 112 errno = 0; 113 ASSERT_EQ(-1, raise(-1)); 114 ASSERT_EQ(EINVAL, errno); 115} 116 117static void raise_in_signal_handler_helper(int signal_number) { 118 ASSERT_EQ(SIGALRM, signal_number); 119 static int count = 0; 120 if (++count == 1) { 121 raise(SIGALRM); 122 } 123} 124 125TEST(signal, raise_in_signal_handler) { 126 ScopedSignalHandler ssh(SIGALRM, raise_in_signal_handler_helper); 127 raise(SIGALRM); 128} 129 130static void HandleSIGALRM(int signal_number) { 131 ASSERT_EQ(SIGALRM, signal_number); 132} 133 134TEST(signal, sigwait) { 135 ScopedSignalHandler ssh(SIGALRM, HandleSIGALRM); 136 137 sigset_t wait_set; 138 sigemptyset(&wait_set); 139 sigaddset(&wait_set, SIGALRM); 140 141 alarm(1); 142 143 int received_signal; 144 errno = 0; 145 ASSERT_EQ(0, sigwait(&wait_set, &received_signal)); 146 ASSERT_EQ(0, errno); 147 ASSERT_EQ(SIGALRM, received_signal); 148} 149 150static int g_sigsuspend_test_helper_call_count = 0; 151 152static void SigSuspendTestHelper(int) { 153 ++g_sigsuspend_test_helper_call_count; 154} 155 156TEST(signal, sigsuspend_sigpending) { 157 // Block SIGALRM. 158 sigset_t just_SIGALRM; 159 sigemptyset(&just_SIGALRM); 160 sigaddset(&just_SIGALRM, SIGALRM); 161 sigset_t original_set; 162 ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); 163 164 ScopedSignalHandler ssh(SIGALRM, SigSuspendTestHelper); 165 166 // There should be no pending signals. 167 sigset_t pending; 168 sigemptyset(&pending); 169 ASSERT_EQ(0, sigpending(&pending)); 170 for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) { 171 EXPECT_FALSE(sigismember(&pending, i)) << i; 172 } 173 174 // Raise SIGALRM and check our signal handler wasn't called. 175 raise(SIGALRM); 176 ASSERT_EQ(0, g_sigsuspend_test_helper_call_count); 177 178 // We should now have a pending SIGALRM but nothing else. 179 sigemptyset(&pending); 180 ASSERT_EQ(0, sigpending(&pending)); 181 for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) { 182 EXPECT_EQ((i == SIGALRM), sigismember(&pending, i)); 183 } 184 185 // Use sigsuspend to block everything except SIGALRM... 186 sigset_t not_SIGALRM; 187 sigfillset(¬_SIGALRM); 188 sigdelset(¬_SIGALRM, SIGALRM); 189 ASSERT_EQ(-1, sigsuspend(¬_SIGALRM)); 190 ASSERT_EQ(EINTR, errno); 191 // ...and check that we now receive our pending SIGALRM. 192 ASSERT_EQ(1, g_sigsuspend_test_helper_call_count); 193 194 // Restore the original set. 195 ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); 196} 197 198static void EmptySignalHandler(int) {} 199static void EmptySignalAction(int, siginfo_t*, void*) {} 200 201TEST(signal, sigaction) { 202 // Both bionic and glibc set SA_RESTORER when talking to the kernel on arm, 203 // arm64, x86, and x86-64. The version of glibc we're using also doesn't 204 // define SA_RESTORER, but luckily it's the same value everywhere, and mips 205 // doesn't use the bit for anything. 206 static const unsigned sa_restorer = 0x4000000; 207 208 // See what's currently set for SIGALRM. 209 struct sigaction original_sa; 210 memset(&original_sa, 0, sizeof(original_sa)); 211 ASSERT_EQ(0, sigaction(SIGALRM, NULL, &original_sa)); 212 ASSERT_TRUE(original_sa.sa_handler == NULL); 213 ASSERT_TRUE(original_sa.sa_sigaction == NULL); 214 ASSERT_EQ(0U, original_sa.sa_flags & ~sa_restorer); 215 216 // Set a traditional sa_handler signal handler. 217 struct sigaction sa; 218 memset(&sa, 0, sizeof(sa)); 219 sigaddset(&sa.sa_mask, SIGALRM); 220 sa.sa_flags = SA_ONSTACK; 221 sa.sa_handler = EmptySignalHandler; 222 ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL)); 223 224 // Check that we can read it back. 225 memset(&sa, 0, sizeof(sa)); 226 ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa)); 227 ASSERT_TRUE(sa.sa_handler == EmptySignalHandler); 228 ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler); 229 ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK), sa.sa_flags & ~sa_restorer); 230 231 // Set a new-style sa_sigaction signal handler. 232 memset(&sa, 0, sizeof(sa)); 233 sigaddset(&sa.sa_mask, SIGALRM); 234 sa.sa_flags = SA_ONSTACK | SA_SIGINFO; 235 sa.sa_sigaction = EmptySignalAction; 236 ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL)); 237 238 // Check that we can read it back. 239 memset(&sa, 0, sizeof(sa)); 240 ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa)); 241 ASSERT_TRUE(sa.sa_sigaction == EmptySignalAction); 242 ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler); 243 ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK | SA_SIGINFO), sa.sa_flags & ~sa_restorer); 244 245 // Put everything back how it was. 246 ASSERT_EQ(0, sigaction(SIGALRM, &original_sa, NULL)); 247} 248 249TEST(signal, sys_signame) { 250#if defined(__BIONIC__) 251 ASSERT_TRUE(sys_signame[0] == NULL); 252 ASSERT_STREQ("HUP", sys_signame[SIGHUP]); 253#else 254 GTEST_LOG_(INFO) << "This test does nothing.\n"; 255#endif 256} 257 258TEST(signal, sys_siglist) { 259 ASSERT_TRUE(sys_siglist[0] == NULL); 260 ASSERT_STREQ("Hangup", sys_siglist[SIGHUP]); 261} 262 263TEST(signal, limits) { 264 // This comes from the kernel. 265 ASSERT_EQ(32, __SIGRTMIN); 266 267 // We reserve a non-zero number at the bottom for ourselves. 268 ASSERT_GT(SIGRTMIN, __SIGRTMIN); 269 270 // MIPS has more signals than everyone else. 271#if defined(__mips__) 272 ASSERT_EQ(128, __SIGRTMAX); 273#else 274 ASSERT_EQ(64, __SIGRTMAX); 275#endif 276 277 // We don't currently reserve any at the top. 278 ASSERT_EQ(SIGRTMAX, __SIGRTMAX); 279} 280 281static int g_sigqueue_signal_handler_call_count = 0; 282 283static void SigqueueSignalHandler(int signum, siginfo_t* info, void*) { 284 ASSERT_EQ(SIGALRM, signum); 285 ASSERT_EQ(SIGALRM, info->si_signo); 286 ASSERT_EQ(SI_QUEUE, info->si_code); 287 ASSERT_EQ(1, info->si_value.sival_int); 288 ++g_sigqueue_signal_handler_call_count; 289} 290 291TEST(signal, sigqueue) { 292 ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO); 293 sigval_t sigval; 294 sigval.sival_int = 1; 295 errno = 0; 296 ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval)); 297 ASSERT_EQ(0, errno); 298 ASSERT_EQ(1, g_sigqueue_signal_handler_call_count); 299} 300 301TEST(signal, sigwaitinfo) { 302 // Block SIGALRM. 303 sigset_t just_SIGALRM; 304 sigemptyset(&just_SIGALRM); 305 sigaddset(&just_SIGALRM, SIGALRM); 306 sigset_t original_set; 307 ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); 308 309 // Raise SIGALRM. 310 sigval_t sigval; 311 sigval.sival_int = 1; 312 ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval)); 313 314 // Get pending SIGALRM. 315 siginfo_t info; 316 errno = 0; 317 ASSERT_EQ(SIGALRM, sigwaitinfo(&just_SIGALRM, &info)); 318 ASSERT_EQ(0, errno); 319 ASSERT_EQ(SIGALRM, info.si_signo); 320 ASSERT_EQ(1, info.si_value.sival_int); 321 322 ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); 323} 324 325TEST(signal, sigtimedwait) { 326 // Block SIGALRM. 327 sigset_t just_SIGALRM; 328 sigemptyset(&just_SIGALRM); 329 sigaddset(&just_SIGALRM, SIGALRM); 330 sigset_t original_set; 331 ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); 332 333 // Raise SIGALRM. 334 sigval_t sigval; 335 sigval.sival_int = 1; 336 ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval)); 337 338 // Get pending SIGALRM. 339 siginfo_t info; 340 struct timespec timeout; 341 timeout.tv_sec = 2; 342 timeout.tv_nsec = 0; 343 errno = 0; 344 ASSERT_EQ(SIGALRM, sigtimedwait(&just_SIGALRM, &info, &timeout)); 345 ASSERT_EQ(0, errno); 346 347 ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); 348} 349 350static int64_t NanoTime() { 351 struct timespec t; 352 t.tv_sec = t.tv_nsec = 0; 353 clock_gettime(CLOCK_MONOTONIC, &t); 354 return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec; 355} 356 357TEST(signal, sigtimedwait_timeout) { 358 // Block SIGALRM. 359 sigset_t just_SIGALRM; 360 sigemptyset(&just_SIGALRM); 361 sigaddset(&just_SIGALRM, SIGALRM); 362 sigset_t original_set; 363 ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); 364 365 // Wait timeout. 366 int64_t start_time = NanoTime(); 367 siginfo_t info; 368 struct timespec timeout; 369 timeout.tv_sec = 0; 370 timeout.tv_nsec = 1000000; 371 errno = 0; 372 ASSERT_EQ(-1, sigtimedwait(&just_SIGALRM, &info, &timeout)); 373 ASSERT_EQ(EAGAIN, errno); 374 ASSERT_GE(NanoTime() - start_time, 1000000); 375 376 ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); 377} 378