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 %d Thread %d %s\n", getpid(), gettid(), msg); fflush(stdout);
     30 }
     31 
     32 static int int_und;
     33 static int sleeps = 15;
     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 
     47 static void level ()
     48 {
     49   char *level_name __attribute__((unused)) = "level name";
     50   make_error ("called from level");
     51 }
     52 
     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 
     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 }
     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 }
     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 }
     97 static void leaf(void) {}
     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 }
    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