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
usechar(char c)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
err(void)23 __attribute__((noinline)) void err ( void )
24 {
25 usechar( block[5] );
26 }
27
child_fn(void * arg)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
main(void)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