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