65 lines · c
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 %t4// Missing 'getcontext' and 'makecontext' on Android.5// UNSUPPORTED: android6 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 14pthread_cond_t cond = PTHREAD_COND_INITIALIZER;15pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;16int ctxfunc_started = 0;17 18static 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 25static 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 35static 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 53int 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