#define _GNU_SOURCE #include <pthread.h> #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <config.h> /* test based on code from Jeffrey Yasskin, slightly modified. */ /* Reproduces a false positive leak when a pointer is (only) in a live thread register, and another thread calls exit */ pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER; int cont = 1; void* helper(void* v_bar) { pthread_barrier_t* bar = (pthread_barrier_t*)v_bar; register int* i = malloc(sizeof(*i)); // Try hard to have i allocated in a register. *i = 3; pthread_barrier_wait(bar); pthread_mutex_lock(&mu); while (cont) { #if defined(VGA_x86) || defined(VGA_amd64) // Below helps to have i really in a register. asm volatile("test %0, %0" : : "S"(i)); #else // Not clear that for other archs, i is in a register. if (*i) // should do better for other archs. // "then" part after the #endif #endif pthread_mutex_unlock(&mu); sched_yield(); pthread_mutex_lock(&mu); } pthread_mutex_unlock(&mu); free((void *)i); fprintf(stderr, "Quitting the helper.\n"); return NULL; } int main() { pthread_barrier_t bar; pthread_barrier_init(&bar, NULL, 2); pthread_t thr; pthread_create(&thr, NULL, &helper, &bar); pthread_barrier_wait(&bar); pthread_barrier_destroy(&bar); fprintf(stderr, "Abandoning the helper.\n"); pthread_detach(thr); return 0; }