• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
helper(void * v_bar)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 
main()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