Home | History | Annotate | Download | only in TestCases
      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;
     25   pthread_cond_signal(&cond);
     26   pthread_mutex_unlock(&mutex);
     27   // Leave this context alive when the program exits.
     28   for (;;);
     29 }
     30 
     31 static void* thread(void* arg) {
     32   (void)arg;
     33   ucontext_t ctx;
     34   void* stack;
     35 
     36   if (getcontext(&ctx) < 0)
     37     die("getcontext", 0);
     38   stack = malloc(1 << 10);
     39   if (stack == NULL)
     40     die("malloc", 0);
     41   ctx.uc_stack.ss_sp = stack;
     42   ctx.uc_stack.ss_size = 1 << 10;
     43   makecontext(&ctx, ctxfunc, 0);
     44   setcontext(&ctx);
     45   die("setcontext", 0);
     46   return NULL;
     47 }
     48 
     49 int main() {
     50   pthread_t tid;
     51   int i;
     52 
     53   pthread_mutex_lock(&mutex);
     54   i = pthread_create(&tid, NULL, thread, NULL);
     55   if (i != 0)
     56     die("pthread_create", i);
     57   while (!ctxfunc_started) pthread_cond_wait(&cond, &mutex);
     58   pthread_mutex_unlock(&mutex);
     59   return 0;
     60 }
     61