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