1 //===-- Unittests for sigaltstack -----------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "hdr/signal_macros.h"
10 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
11 #include "src/errno/libc_errno.h"
12 #include "src/signal/linux/signal_utils.h"
13 #include "src/signal/raise.h"
14 #include "src/signal/sigaction.h"
15 #include "src/signal/sigaltstack.h"
16 #include "test/UnitTest/ErrnoSetterMatcher.h"
17 #include "test/UnitTest/Test.h"
20 #include <sys/syscall.h>
22 constexpr int LOCAL_VAR_SIZE
= 512;
23 constexpr int ALT_STACK_SIZE
= SIGSTKSZ
+ LOCAL_VAR_SIZE
* 2;
24 static uint8_t alt_stack
[ALT_STACK_SIZE
];
26 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails
;
27 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds
;
29 static bool good_stack
;
30 static void handler(int) {
31 // Allocate a large stack variable so that it does not get optimized
32 // out or mapped to a register.
33 uint8_t var
[LOCAL_VAR_SIZE
];
34 for (int i
= 0; i
< LOCAL_VAR_SIZE
; ++i
)
36 // Verify that array is completely on the alt_stack.
37 for (int i
= 0; i
< LOCAL_VAR_SIZE
; ++i
) {
38 if (!(uintptr_t(var
+ i
) < uintptr_t(alt_stack
+ ALT_STACK_SIZE
) &&
39 uintptr_t(alt_stack
) <= uintptr_t(var
+ i
))) {
47 TEST(LlvmLibcSignalTest
, SigaltstackRunOnAltStack
) {
48 struct sigaction action
;
49 LIBC_NAMESPACE::libc_errno
= 0;
50 ASSERT_THAT(LIBC_NAMESPACE::sigaction(SIGUSR1
, nullptr, &action
),
52 action
.sa_handler
= handler
;
53 // Indicate that the signal should be delivered on an alternate stack.
54 action
.sa_flags
= SA_ONSTACK
;
55 ASSERT_THAT(LIBC_NAMESPACE::sigaction(SIGUSR1
, &action
, nullptr),
60 ss
.ss_size
= ALT_STACK_SIZE
;
62 // Setup the alternate stack.
63 ASSERT_THAT(LIBC_NAMESPACE::sigaltstack(&ss
, nullptr), Succeeds(0));
66 LIBC_NAMESPACE::raise(SIGUSR1
);
67 EXPECT_TRUE(good_stack
);
70 // This tests for invalid input.
71 TEST(LlvmLibcSignalTest
, SigaltstackInvalidStack
) {
75 ss
.ss_flags
= SS_ONSTACK
;
76 ASSERT_THAT(LIBC_NAMESPACE::sigaltstack(&ss
, nullptr), Fails(EINVAL
));
79 ASSERT_THAT(LIBC_NAMESPACE::sigaltstack(&ss
, nullptr), Fails(ENOMEM
));