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