• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <string.h>
2 #include <pthread.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <fcntl.h>
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <sys/syscall.h>
9 #include "../memcheck/memcheck.h"
10 int using_threads = 0; /* test collision with a global in gdbserver */
11 /* we will undefine one char on two */
12 static char undefined[10] = "undefined";
13 
14 #define LOOPS 10000000
15 static int loopmain, loopt1, loopt2;
16 
17 static double pi = 3.14159265358979323846264338327950288;
18 
gettid()19 static pid_t gettid()
20 {
21 #ifdef __NT_gettid
22    return syscall(__NR_gettid);
23 #else
24    return getpid();
25 #endif
26 }
whoami(char * msg)27 static void whoami(char *msg)
28 {
29    printf("pid %d Thread %d %s\n", getpid(), gettid(), msg); fflush(stdout);
30 }
31 
32 static int int_und;
33 static int sleeps = 15;
make_error(char * s)34 static 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 
level()47 static void level ()
48 {
49   char *level_name __attribute__((unused)) = "level name";
50   make_error ("called from level");
51 }
52 
loops(int * loopnr)53 static 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 
brussels_fn(void * v)61 static 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 }
london_fn(void * v)71 static 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 }
petaouchnok_fn(void * v)82 static 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 }
leaf(void)97 static void leaf(void) {}
breakme(int line)98 static void breakme(int line)
99 {
100    if (line > 1000)
101       leaf(); // ensures not leaf, as ppc unwind implies VEX iropt precise exns
102 }
main(int argc,char * argv[])103 int 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