1 #define _GNU_SOURCE 2 3 #include <pthread.h> 4 #include <sched.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <unistd.h> 8 #include <config.h> 9 10 /* test based on code from Jeffrey Yasskin, slightly modified. */ 11 /* Reproduces a false positive leak when a pointer is (only) in a live 12 thread register, and another thread calls exit */ 13 14 pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER; 15 int cont = 1; 16 17 void* helper(void* v_bar) { 18 pthread_barrier_t* bar = (pthread_barrier_t*)v_bar; 19 register int* i = malloc(sizeof(*i)); 20 // Try hard to have i allocated in a register. 21 *i = 3; 22 pthread_barrier_wait(bar); 23 pthread_mutex_lock(&mu); 24 while (cont) { 25 #if defined(VGA_x86) || defined(VGA_amd64) 26 // Below helps to have i really in a register. 27 asm volatile("test %0, %0" : : "S"(i)); 28 #else 29 // Not clear that for other archs, i is in a register. 30 if (*i) // should do better for other archs. 31 // "then" part after the #endif 32 #endif 33 pthread_mutex_unlock(&mu); 34 sched_yield(); 35 pthread_mutex_lock(&mu); 36 } 37 pthread_mutex_unlock(&mu); 38 free((void *)i); 39 fprintf(stderr, "Quitting the helper.\n"); 40 return NULL; 41 } 42 43 int main() { 44 pthread_barrier_t bar; 45 pthread_barrier_init(&bar, NULL, 2); 46 pthread_t thr; 47 pthread_create(&thr, NULL, &helper, &bar); 48 pthread_barrier_wait(&bar); 49 pthread_barrier_destroy(&bar); 50 fprintf(stderr, "Abandoning the helper.\n"); 51 pthread_detach(thr); 52 return 0; 53 } 54