1//===-- Unittests for sigaltstack -----------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include "hdr/signal_macros.h"
10#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
11#include "src/__support/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"
18
19#include <stdint.h>
20#include <sys/syscall.h>
21
22constexpr int LOCAL_VAR_SIZE = 512;
23constexpr int ALT_STACK_SIZE = SIGSTKSZ + LOCAL_VAR_SIZE * 2;
24static uint8_t alt_stack[ALT_STACK_SIZE];
25
26using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
27using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
28
29static bool good_stack;
30static 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)
35 var[i] = 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))) {
40 good_stack = false;
41 return;
42 }
43 }
44 good_stack = true;
45}
46
47TEST(LlvmLibcSignalTest, SigaltstackRunOnAltStack) {
48 struct sigaction action;
49 libc_errno = 0;
50 ASSERT_THAT(LIBC_NAMESPACE::sigaction(SIGUSR1, nullptr, &action),
51 Succeeds(0));
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),
56 Succeeds(0));
57
58 stack_t ss;
59 ss.ss_sp = alt_stack;
60 ss.ss_size = ALT_STACK_SIZE;
61 ss.ss_flags = 0;
62 // Setup the alternate stack.
63 ASSERT_THAT(LIBC_NAMESPACE::sigaltstack(&ss, nullptr), Succeeds(0));
64
65 good_stack = false;
66 LIBC_NAMESPACE::raise(SIGUSR1);
67 EXPECT_TRUE(good_stack);
68}
69
70// This tests for invalid input.
71TEST(LlvmLibcSignalTest, SigaltstackInvalidStack) {
72 stack_t ss;
73 ss.ss_sp = alt_stack;
74 ss.ss_size = 0;
75 ss.ss_flags = SS_ONSTACK;
76 ASSERT_THAT(LIBC_NAMESPACE::sigaltstack(&ss, nullptr), Fails(EINVAL));
77
78 ss.ss_flags = 0;
79 ASSERT_THAT(LIBC_NAMESPACE::sigaltstack(&ss, nullptr), Fails(ENOMEM));
80}
81

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of libc/test/src/signal/sigaltstack_test.cpp