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 13char* 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 28void* 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 36int 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