]>
Commit | Line | Data |
---|---|---|
5bcae85e SL |
1 | // Check that if LSan finds that SP doesn't point into thread stack (e.g. |
2 | // if swapcontext is used), LSan will not hit the guard page. | |
3 | // RUN: %clang_lsan %s -o %t && %run %t | |
4 | #include <errno.h> | |
5 | #include <stdio.h> | |
6 | #include <stdlib.h> | |
7 | #include <string.h> | |
8 | #include <pthread.h> | |
9 | #include <ucontext.h> | |
10 | ||
11 | pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | |
12 | pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | |
13 | int ctxfunc_started = 0; | |
14 | ||
15 | static void die(const char* msg, int err) { | |
16 | if (err == 0) | |
17 | err = errno; | |
18 | fprintf(stderr, "%s: %s\n", msg, strerror(err)); | |
19 | exit(EXIT_FAILURE); | |
20 | } | |
21 | ||
22 | static void ctxfunc() { | |
23 | pthread_mutex_lock(&mutex); | |
24 | ctxfunc_started = 1; | |
7cac9316 | 25 | // printf("ctxfunc\n"); |
5bcae85e SL |
26 | pthread_cond_signal(&cond); |
27 | pthread_mutex_unlock(&mutex); | |
28 | // Leave this context alive when the program exits. | |
29 | for (;;); | |
30 | } | |
31 | ||
32 | static void* thread(void* arg) { | |
33 | (void)arg; | |
34 | ucontext_t ctx; | |
35 | void* stack; | |
36 | ||
37 | if (getcontext(&ctx) < 0) | |
38 | die("getcontext", 0); | |
7cac9316 | 39 | stack = malloc(1 << 11); |
5bcae85e SL |
40 | if (stack == NULL) |
41 | die("malloc", 0); | |
42 | ctx.uc_stack.ss_sp = stack; | |
7cac9316 | 43 | ctx.uc_stack.ss_size = 1 << 11; |
5bcae85e SL |
44 | makecontext(&ctx, ctxfunc, 0); |
45 | setcontext(&ctx); | |
46 | die("setcontext", 0); | |
47 | return NULL; | |
48 | } | |
49 | ||
50 | int main() { | |
51 | pthread_t tid; | |
52 | int i; | |
53 | ||
54 | pthread_mutex_lock(&mutex); | |
55 | i = pthread_create(&tid, NULL, thread, NULL); | |
56 | if (i != 0) | |
57 | die("pthread_create", i); | |
58 | while (!ctxfunc_started) pthread_cond_wait(&cond, &mutex); | |
59 | pthread_mutex_unlock(&mutex); | |
60 | return 0; | |
61 | } |