]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/test/stress2/misc/sigaltstack.sh
contrib/bc: update to version 5.1.1
[FreeBSD/FreeBSD.git] / tools / test / stress2 / misc / sigaltstack.sh
1 #!/bin/sh
2
3 # sigaltstack(2) regression test by Steven Hartland <killing@multiplay.co.uk>
4 # Wrong altsigstack clearing on exec
5 # https://github.com/golang/go/issues/15658#issuecomment-287276856
6
7 # Fixed by r315453
8
9 cd /tmp
10 cat > test-sigs.c <<EOF
11 #include <errno.h>
12 #include <signal.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <time.h>
18 #include <pthread.h>
19
20 extern char **environ;
21
22 static void
23 die(const char *s)
24 {
25        perror(s);
26        exit(EXIT_FAILURE);
27 }
28
29 static void
30 setstack(void *arg __unused)
31 {
32         stack_t ss;
33
34         ss.ss_sp = malloc(SIGSTKSZ);
35         if (ss.ss_sp == NULL)
36                 die("malloc");
37
38         ss.ss_size = SIGSTKSZ;
39         ss.ss_flags = 0;
40         if (sigaltstack(&ss, NULL) < 0)
41                 die("sigaltstack set");
42 }
43
44 static void *
45 thread_exec(void *arg)
46 {
47         struct timespec ts = {0, 1000};
48         char *argv[] = {"./test-sigs", "no-more", 0};
49
50         setstack(arg);
51         nanosleep(&ts, NULL);
52
53         execve(argv[0], &argv[0], environ);
54         die("exec failed");
55
56         return NULL;
57 }
58
59 static void *
60 thread_sleep(void *arg __unused)
61 {
62         sleep(10);
63
64         return NULL;
65 }
66
67 int
68 main(int argc, char** argv __unused)
69 {
70         int j;
71         pthread_t tid1, tid2;
72
73         if (argc != 1) {
74                 stack_t ss;
75
76                 if (sigaltstack(NULL, &ss) < 0)
77                         die("sigaltstack get");
78
79                 if (ss.ss_sp != NULL || ss.ss_flags != SS_DISABLE ||
80                     ss.ss_size != 0) {
81                         fprintf(stderr, "invalid signal stack after execve: "
82                             "ss_sp=%p ss_size=%lu ss_flags=0x%x\n", ss.ss_sp,
83                             (unsigned long)ss.ss_size,
84                             (unsigned int)ss.ss_flags);
85                         return 1;
86                 }
87
88                 printf("valid signal stack is valid after execve\n");
89
90                 return 0;
91         }
92
93         // We have to use two threads to ensure that can detect the
94         // issue when new threads are added to the head (pre 269095)
95         // and the tail of the process thread list.
96         j = pthread_create(&tid1, NULL, thread_exec, NULL);
97         if (j != 0) {
98                errno = j;
99                die("pthread_create");
100         }
101
102         j = pthread_create(&tid2, NULL, thread_sleep, NULL);
103         if (j != 0) {
104                errno = j;
105                die("pthread_create");
106         }
107
108         j = pthread_join(tid1, NULL);
109         if (j != 0) {
110                 errno = j;
111                 die("pthread_join");
112         }
113
114         j = pthread_join(tid2, NULL);
115         if (j != 0) {
116                 errno = j;
117         }
118
119         return 0;
120 }
121 EOF
122
123 cc -o test-sigs -Wall -Wextra -O2 -g test-sigs.c -lpthread || exit 1
124 ./test-sigs
125 s=$?
126
127 rm -f test-sigs test-sigs.c
128 exit $s