1//===-- Unittests for sigsetjmp and siglongjmp ----------------------------===//
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 "src/setjmp/siglongjmp.h"
10#include "src/setjmp/sigsetjmp.h"
11#include "src/signal/sigprocmask.h"
12#include "src/string/memcmp.h"
13#include "src/string/memset.h"
14#include "test/UnitTest/Test.h"
15
16constexpr int MAX_LOOP = 123;
17int longjmp_called = 0;
18
19void jump_back(jmp_buf buf, int n) {
20 longjmp_called++;
21 LIBC_NAMESPACE::siglongjmp(buf, n); // Will return |n| out of setjmp
22}
23
24TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackSaveSigs) {
25 jmp_buf buf;
26 longjmp_called = 0;
27 volatile int n = 0;
28 sigset_t old;
29 sigset_t mask_all;
30 sigset_t recovered;
31 LIBC_NAMESPACE::memset(&mask_all, 0xFF, sizeof(mask_all));
32 LIBC_NAMESPACE::memset(&old, 0, sizeof(old));
33 LIBC_NAMESPACE::memset(&recovered, 0, sizeof(recovered));
34 LIBC_NAMESPACE::sigprocmask(0, nullptr, &old);
35 if (LIBC_NAMESPACE::sigsetjmp(buf, 1) <= MAX_LOOP) {
36 LIBC_NAMESPACE::sigprocmask(0, nullptr, &recovered);
37 ASSERT_EQ(0, LIBC_NAMESPACE::memcmp(&old, &recovered, sizeof(old)));
38 n = n + 1;
39 LIBC_NAMESPACE::sigprocmask(SIG_BLOCK, &mask_all, nullptr);
40 jump_back(buf, n);
41 }
42 ASSERT_EQ(longjmp_called, n);
43 ASSERT_EQ(n, MAX_LOOP + 1);
44}
45
46TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackValOneSaveSigs) {
47 jmp_buf buf;
48 longjmp_called = 0;
49 sigset_t old;
50 sigset_t mask_all;
51 sigset_t recovered;
52 LIBC_NAMESPACE::memset(&mask_all, 0xFF, sizeof(mask_all));
53 LIBC_NAMESPACE::memset(&old, 0, sizeof(old));
54 LIBC_NAMESPACE::memset(&recovered, 0, sizeof(recovered));
55 LIBC_NAMESPACE::sigprocmask(0, nullptr, &old);
56 int val = LIBC_NAMESPACE::sigsetjmp(buf, 1);
57 if (val == 0) {
58 LIBC_NAMESPACE::sigprocmask(SIG_BLOCK, &mask_all, nullptr);
59 jump_back(buf, val);
60 }
61 LIBC_NAMESPACE::sigprocmask(0, nullptr, &recovered);
62 ASSERT_EQ(0, LIBC_NAMESPACE::memcmp(&old, &recovered, sizeof(old)));
63 ASSERT_EQ(longjmp_called, 1);
64 ASSERT_EQ(val, 1);
65}
66
67TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackNoSaveSigs) {
68 jmp_buf buf;
69 longjmp_called = 0;
70 volatile int n = 0;
71 if (LIBC_NAMESPACE::sigsetjmp(buf, 0) <= MAX_LOOP) {
72 n = n + 1;
73 jump_back(buf, n);
74 }
75 ASSERT_EQ(longjmp_called, n);
76 ASSERT_EQ(n, MAX_LOOP + 1);
77}
78
79TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackValOneNoSaveSigs) {
80 jmp_buf buf;
81 longjmp_called = 0;
82 int val = LIBC_NAMESPACE::sigsetjmp(buf, 0);
83 if (val == 0) {
84 jump_back(buf, val);
85 }
86 ASSERT_EQ(longjmp_called, 1);
87 ASSERT_EQ(val, 1);
88}
89

source code of libc/test/src/setjmp/sigsetjmp_test.cpp