Home | History | Annotate | Download | only in tests
      1 
      2 /* Check that a child thread doesn't inherit its parent's disablement
      3    status. */
      4 
      5 #include <stdlib.h>
      6 #include <stdio.h>
      7 #include <assert.h>
      8 #include <pthread.h>
      9 #include <unistd.h>    // sleep
     10 
     11 #include "../include/valgrind.h"
     12 
     13 char* block = NULL;
     14 
     15 __attribute__((noinline)) void usechar ( char c )
     16 {
     17    // Spook gcc into believing mysterious bad things are
     18    // happening behind its back, and that 'c' is definitely
     19    // used in some (unknown) way.
     20    __asm__ __volatile__("" : : "r"(c) : "memory","cc");
     21 }
     22 
     23 __attribute__((noinline)) void err ( void )
     24 {
     25    usechar( block[5] );
     26 }
     27 
     28 void* child_fn ( void* arg )
     29 {
     30    fprintf(stderr, "\n--------- c: start (expect 1) ---------\n\n");
     31    err();
     32    fprintf(stderr, "\n--------- c: end ---------\n\n");
     33    return NULL;
     34 }
     35 
     36 int main ( void )
     37 {
     38   int r;
     39   pthread_t child;
     40 
     41   block = malloc(10);
     42   free(block);
     43 
     44   fprintf(stderr, "\n--------- p: disabling errors (expect 0) ---------\n\n");
     45 
     46   VALGRIND_DISABLE_ERROR_REPORTING;
     47   err();
     48 
     49   fprintf(stderr, "\n--------- p: creating child ---------\n\n");
     50 
     51   r = pthread_create(&child, NULL, child_fn, NULL);
     52   assert(!r);
     53   sleep(1); // let the child run first (determinism fix)
     54   fprintf(stderr, "\n--------- p: join child ---------\n\n");
     55   r = pthread_join(child, NULL);
     56   assert(!r);
     57 
     58   fprintf(stderr, "\n--------- p: re_enabled (expect 1) ---------\n\n");
     59   VALGRIND_ENABLE_ERROR_REPORTING;
     60   err();
     61 
     62   return 0;
     63 }
     64