1f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <string.h>
2f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <pthread.h>
3f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <stdlib.h>
4f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <stdio.h>
5f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <fcntl.h>
6f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <unistd.h>
7f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <sys/types.h>
8f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <sys/syscall.h>
9e73a31f667ad2fe03e25c97ac45b58c30d7f07c3Chris Lattner#include "../memcheck/memcheck.h"
10f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovint using_threads = 0; /* test collision with a global in gdbserver */
11960a7c9ad182f1112a864cc5075990f0cff92e67Anton Korobeynikov/* we will undefine one char on two */
12f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovstatic char undefined[10] = "undefined";
13f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
14f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#define LOOPS 10000000
1522fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Chengstatic int loopmain, loopt1, loopt2;
1622fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovstatic double pi = 3.14159265358979323846264338327950288;
18385e930d55f3ecd3c9538823dfa5896a12461845Evan Cheng
19f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovstatic pid_t gettid()
20c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng{
21c984df8602a8b2450cbdb6ff55fd49ba709a391eDaniel Dunbar#ifdef __NT_gettid
22f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov   return syscall(__NR_gettid);
23f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#else
24   return getpid();
25#endif
26}
27static void whoami(char *msg)
28{
29   printf("pid %d Thread %d %s\n", getpid(), gettid(), msg); fflush(stdout);
30}
31
32static int int_und;
33static int sleeps = 15;
34static void make_error (char *s)
35{
36  char *make_error_name __attribute__((unused)) = "make_error name";
37  char c __attribute__((unused));
38  double pi2 __attribute__((unused)) = 2.0 * pi;
39  whoami(s);
40  if (int_und == 0)
41     printf ("%s int_und is zero %d\n", s, int_und);
42  else
43     printf ("%s int_und is not zero\n", s);
44  fflush(stdout);
45}
46
47static void level ()
48{
49  char *level_name __attribute__((unused)) = "level name";
50  make_error ("called from level");
51}
52
53static void loops (int *loopnr)
54{
55  int i, j;
56  for (i = 0; i < LOOPS; i++)
57    for (j = 0; j < LOOPS; j++)
58      (*loopnr)++;
59}
60
61static void *brussels_fn(void *v)
62{
63  char *brussels_name __attribute__((unused)) = "Brussels";
64  make_error ("called from Brussels");
65  loopt1 = 1;
66  while (! (loopt1 && loopt2 && loopmain))
67    loopt1++;
68  loops (&loopt1);
69  return NULL;
70}
71static void *london_fn(void *v)
72{
73  char *london_name __attribute__((unused)) = "London";
74  make_error ("called from London");
75  loopt2 = 1;
76  while (! (loopt1 && loopt2 && loopmain))
77    loopt2++;
78  loops (&loopt2);
79  sleep(10);
80  return NULL;
81}
82static void *petaouchnok_fn(void *v)
83{
84  char *petaouchnok_name __attribute__((unused)) = "Petaouchnok";
85  struct timeval t;
86  int i;
87  for (i = 1; i <= sleeps; i++) {
88      t.tv_sec = 5;
89      t.tv_usec = 0;
90      fprintf (stderr, "Petaouchnok sleep nr %d out of %d sleeping 5 seconds\n",
91               i, sleeps);
92      fflush(stderr);
93      select (0, NULL, NULL, NULL, &t);
94  }
95  return NULL;
96}
97static void leaf(void) {}
98static void breakme(int line)
99{
100   if (line > 1000)
101      leaf(); // ensures not leaf, as ppc unwind implies VEX iropt precise exns
102}
103int main (int argc, char *argv[])
104{
105  char *main_name __attribute__((unused)) = "main name";
106  pthread_t ebbr, egll, zzzz;
107  int i = 1234;
108  char undef = '?';
109  char *some_mem __attribute__((unused)) = malloc(100);
110  VALGRIND_MAKE_MEM_UNDEFINED(&undef, 1);
111  int len = strlen(undefined);
112  breakme(__LINE__); //break1
113  for (i = len-1; i >= 0; i=i-2)
114     undefined[i] = undef;
115  *(char*)&int_und = undef;
116
117  breakme(__LINE__); //break2
118
119  if (argc > 1)
120    sleeps = atoi(argv[1]);
121
122  level();
123  make_error ("called from main");
124
125  pthread_create(&ebbr, NULL, brussels_fn, NULL);
126  pthread_create(&egll, NULL, london_fn, NULL);
127  pthread_create(&zzzz, NULL, petaouchnok_fn, NULL);
128
129  loopmain = 1;
130  while (! (loopt1 && loopt2 && loopmain))
131    loopmain++;
132  for (i = 0; i < LOOPS; i++) {
133     loopmain++;
134
135     if (loopmain == 10000)
136        make_error ("in main loop");
137  }
138
139  pthread_join(ebbr, NULL);
140
141  make_error ("called from main (the end, before joining t3)");
142
143  pthread_join(zzzz, NULL);
144
145  if (argc > 2) {
146     for (i = 0; i < 100; i++)
147        if ((*(&undef + i*4000) == 0) || (*(&undef - i*4000) == 0)) {
148           printf ("there are some null bytes here and there %d\n", i);
149           fflush(stdout);
150        }
151  }
152  exit(0);
153}
154