]> git.ozlabs.org Git - ccan/blob - ccan/altstack/test/run.c
altstack: Don't log internal calls in test cases
[ccan] / ccan / altstack / test / run.c
1 #include "config.h"
2 #include <assert.h>
3 #include <err.h>
4 #include <errno.h>
5 #include <setjmp.h>
6 #include <signal.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <sys/mman.h>
10 #include <ccan/tap/tap.h>
11 #include <ccan/ptrint/ptrint.h>
12 #include <ccan/altstack/altstack.h>
13 #include <stdio.h>
14
15 enum {
16         getrlimit_      = 1<<0,
17         setrlimit_      = 1<<1,
18         mmap_           = 1<<2,
19         sigaltstack_    = 1<<3,
20         sigaction_      = 1<<4,
21         munmap_         = 1<<5,
22 };
23 int fail;
24 char *m_;
25 rlim_t msz_;
26 #define e(x) (900+(x))
27 #define seterr(x) (errno = e(x))
28 #define getrlimit(...)          (fail&getrlimit_        ? (seterr(getrlimit_),          -1) : getrlimit(__VA_ARGS__))
29 #define mmap(...)               (fail&mmap_             ? (seterr(mmap_),       (void *)-1) : mmap(__VA_ARGS__))
30 #define munmap(a, b)            (fail&munmap_           ? (seterr(munmap_),             -1) : munmap(m_=(a), msz_=(b)))
31 #define setrlimit(...)          (fail&setrlimit_        ? (seterr(setrlimit_),          -1) : setrlimit(__VA_ARGS__))
32 #define sigaltstack(...)        (fail&sigaltstack_      ? (seterr(sigaltstack_),        -1) : sigaltstack(__VA_ARGS__))
33 #define sigaction(...)          (fail&sigaction_        ? (seterr(sigaction_),          -1) : sigaction(__VA_ARGS__))
34
35 #define KiB (1024UL)
36 #define MiB (KiB*KiB)
37 #define GiB (MiB*KiB)
38 #define TiB (GiB*KiB)
39
40 FILE *mystderr;
41 #undef stderr
42 #define stderr mystderr
43 #undef ok
44 #include <ccan/altstack/altstack.c>
45 #undef ok
46
47 long used;
48
49 static void __attribute__((optimize("O0"))) dn(unsigned long i)
50 {
51         if (used) used = altstack_used();
52         if (i) dn(--i);
53 }
54 static void *wrap(void *i)
55 {
56         dn(ptr2int(i));
57         return wrap;
58 }
59
60 #define chkfail(x, y, z)                                                \
61         do {                                                            \
62                 errno = 0;                                              \
63                 ok1((fail = x) && (y));                                 \
64                 ok1(errno == (z));                                      \
65         } while (0);
66
67 #define chkok(y, z)                                                     \
68         do {                                                            \
69                 errno = 0;                                              \
70                 fail = 0;                                               \
71                 ok1((y));                                               \
72                 ok1(errno == (z));                                      \
73         } while (0)
74
75 int main(void)
76 {
77         long pgsz = sysconf(_SC_PAGESIZE);
78
79         plan_tests(28);
80
81         chkfail(getrlimit_,     altstack(8*MiB, wrap, int2ptr(0), NULL) == -1, e(getrlimit_));
82
83         chkfail(setrlimit_,     altstack(8*MiB, wrap, int2ptr(0), NULL) == -1, e(setrlimit_));
84
85         chkfail(mmap_,          altstack(8*MiB, wrap, int2ptr(0), NULL) == -1, e(mmap_));
86
87         chkfail(sigaltstack_,   altstack(8*MiB, wrap, int2ptr(0), NULL) == -1, e(sigaltstack_));
88
89         chkfail(sigaction_,     altstack(8*MiB, wrap, int2ptr(0), NULL) == -1, e(sigaction_));
90
91         chkfail(munmap_,        altstack(8*MiB, wrap, int2ptr(0), NULL) ==  1, e(munmap_));
92         if (fail = 0, munmap(m_, msz_) == -1)
93                 err(1, "munmap");
94
95         chkok(                  altstack(1*MiB, wrap, int2ptr(1000000), NULL) == -1, EOVERFLOW);
96
97         // be sure segv catch is repeatable (SA_NODEFER)
98         chkok(                  altstack(1*MiB, wrap, int2ptr(1000000), NULL) == -1, EOVERFLOW);
99
100         used = 1;
101         chkfail(munmap_,        altstack(1*MiB, wrap, int2ptr(1000000), NULL) == -1, EOVERFLOW);
102         if (fail = 0, munmap(m_, msz_) == -1)
103                 err(1, "munmap");
104
105         ok1(altstack_max() == 1*MiB);
106         diag("used: %lu", used);
107         ok1(used >= 1*MiB - pgsz && used <= 1*MiB + pgsz);
108
109         char *p;
110         for(p = altstack_geterr(); *p; p++)
111                 if (*p >= '0' && *p <= '9')
112                         *p = '~';
113
114         #define estr "(altstack@~~~) SIGSEGV caught; (altstack@~~~) munmap(m, max): Unknown error ~~~"
115         ok1(strcmp(altstack_geterr(), estr) == 0);
116
117         char buf[ALTSTACK_ERR_MAXLEN*2] = {0};
118         if ((mystderr = fmemopen(buf, sizeof(buf), "w")) == NULL)
119                 err(1, "fmemopen");
120
121         altstack_perror();
122         fflush(mystderr);
123         ok1(strcmp(buf, estr "\n") == 0);
124
125         used = 1;
126         chkok(                  altstack(8*MiB, wrap, int2ptr(1000000), NULL) == -1, EOVERFLOW);
127
128         diag("used: %lu", used);
129         ok1(used >= 8*MiB - pgsz && used <= 8*MiB + pgsz);
130
131         used = 0;
132         chkok(                  altstack(8*MiB, wrap, int2ptr(100000), NULL) == 0, 0);
133
134         used = 1;
135         altstack_rsp_save();
136         dn(0);
137         diag("used: %lu", used);
138         ok1(used == 32 || used == 40);
139
140         return exit_status();
141 }