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