• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Missing 'getcontext' and 'makecontext' on Android.
5 // UNSUPPORTED: android
6 
7 #include <errno.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <pthread.h>
12 #include <ucontext.h>
13 
14 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
15 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
16 int ctxfunc_started = 0;
17 
die(const char * msg,int err)18 static void die(const char* msg, int err) {
19   if (err == 0)
20     err = errno;
21   fprintf(stderr, "%s: %s\n", msg, strerror(err));
22   exit(EXIT_FAILURE);
23 }
24 
ctxfunc()25 static void ctxfunc() {
26   pthread_mutex_lock(&mutex);
27   ctxfunc_started = 1;
28   // printf("ctxfunc\n");
29   pthread_cond_signal(&cond);
30   pthread_mutex_unlock(&mutex);
31   // Leave this context alive when the program exits.
32   for (;;);
33 }
34 
thread(void * arg)35 static void* thread(void* arg) {
36   (void)arg;
37   ucontext_t ctx;
38   void* stack;
39 
40   if (getcontext(&ctx) < 0)
41     die("getcontext", 0);
42   stack = malloc(1 << 12);
43   if (stack == NULL)
44     die("malloc", 0);
45   ctx.uc_stack.ss_sp = stack;
46   ctx.uc_stack.ss_size = 1 << 12;
47   makecontext(&ctx, ctxfunc, 0);
48   setcontext(&ctx);
49   die("setcontext", 0);
50   return NULL;
51 }
52 
main()53 int main() {
54   pthread_t tid;
55   int i;
56 
57   pthread_mutex_lock(&mutex);
58   i = pthread_create(&tid, NULL, thread, NULL);
59   if (i != 0)
60     die("pthread_create", i);
61   while (!ctxfunc_started) pthread_cond_wait(&cond, &mutex);
62   pthread_mutex_unlock(&mutex);
63   return 0;
64 }
65