ftmemsim-valgrind/memcheck/tests/reach_thread_register.c
Philippe Waroquiers 81d7bfddde Fix 324227 memcheck false positive leak when a thread calls exit+block
only reachable via other thread live register

The exiting thread will have its registers considered as not reachable
anymore, registers of other threads will be considered reachable.

This is ensured by using a different exit reason for the
exiting thread and for the other threads.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13670
2013-10-21 19:57:08 +00:00

52 lines
1.4 KiB
C

#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <config.h>
/* test based on code from Alexander Potapenko, 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;
}