mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-08 08:26:14 +00:00
155 lines
3.6 KiB
C
155 lines
3.6 KiB
C
#include <string.h>
|
|
#include <pthread.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/syscall.h>
|
|
#include "../memcheck/memcheck.h"
|
|
int using_threads = 0; /* test collision with a global in gdbserver */
|
|
/* we will undefine one char on two */
|
|
static char undefined[10] = "undefined";
|
|
|
|
#define LOOPS 10000000
|
|
static int loopmain, loopt1, loopt2;
|
|
|
|
static double pi = 3.14159265358979323846264338327950288;
|
|
|
|
static pid_t gettid()
|
|
{
|
|
#ifdef __NT_gettid
|
|
return syscall(__NR_gettid);
|
|
#else
|
|
return getpid();
|
|
#endif
|
|
}
|
|
static void whoami(char *msg)
|
|
{
|
|
printf("pid %ld Thread %ld %s\n", (long) getpid(), (long) gettid(), msg);
|
|
fflush(stdout);
|
|
}
|
|
|
|
static int int_und;
|
|
static int sleeps = 15;
|
|
static void make_error (char *s)
|
|
{
|
|
char *make_error_name __attribute__((unused)) = "make_error name";
|
|
char c __attribute__((unused));
|
|
double pi2 __attribute__((unused)) = 2.0 * pi;
|
|
whoami(s);
|
|
if (int_und == 0)
|
|
printf ("%s int_und is zero %d\n", s, int_und);
|
|
else
|
|
printf ("%s int_und is not zero\n", s);
|
|
fflush(stdout);
|
|
}
|
|
|
|
static void level ()
|
|
{
|
|
char *level_name __attribute__((unused)) = "level name";
|
|
make_error ("called from level");
|
|
}
|
|
|
|
static void loops (int *loopnr)
|
|
{
|
|
int i, j;
|
|
for (i = 0; i < LOOPS; i++)
|
|
for (j = 0; j < LOOPS; j++)
|
|
(*loopnr)++;
|
|
}
|
|
|
|
static void *brussels_fn(void *v)
|
|
{
|
|
char *brussels_name __attribute__((unused)) = "Brussels";
|
|
make_error ("called from Brussels");
|
|
loopt1 = 1;
|
|
while (! (loopt1 && loopt2 && loopmain))
|
|
loopt1++;
|
|
loops (&loopt1);
|
|
return NULL;
|
|
}
|
|
static void *london_fn(void *v)
|
|
{
|
|
char *london_name __attribute__((unused)) = "London";
|
|
make_error ("called from London");
|
|
loopt2 = 1;
|
|
while (! (loopt1 && loopt2 && loopmain))
|
|
loopt2++;
|
|
loops (&loopt2);
|
|
sleep(10);
|
|
return NULL;
|
|
}
|
|
static void *petaouchnok_fn(void *v)
|
|
{
|
|
char *petaouchnok_name __attribute__((unused)) = "Petaouchnok";
|
|
struct timeval t;
|
|
int i;
|
|
for (i = 1; i <= sleeps; i++) {
|
|
t.tv_sec = 5;
|
|
t.tv_usec = 0;
|
|
fprintf (stderr, "Petaouchnok sleep nr %d out of %d sleeping 5 seconds\n",
|
|
i, sleeps);
|
|
fflush(stderr);
|
|
select (0, NULL, NULL, NULL, &t);
|
|
}
|
|
return NULL;
|
|
}
|
|
static void leaf(void) {}
|
|
static void breakme(int line)
|
|
{
|
|
if (line > 1000)
|
|
leaf(); // ensures not leaf, as ppc unwind implies VEX iropt precise exns
|
|
}
|
|
int main (int argc, char *argv[])
|
|
{
|
|
char *main_name __attribute__((unused)) = "main name";
|
|
pthread_t ebbr, egll, zzzz;
|
|
int i = 1234;
|
|
char undef = '?';
|
|
char *some_mem __attribute__((unused)) = malloc(100);
|
|
VALGRIND_MAKE_MEM_UNDEFINED(&undef, 1);
|
|
int len = strlen(undefined);
|
|
breakme(__LINE__); //break1
|
|
for (i = len-1; i >= 0; i=i-2)
|
|
undefined[i] = undef;
|
|
*(char*)&int_und = undef;
|
|
|
|
breakme(__LINE__); //break2
|
|
|
|
if (argc > 1)
|
|
sleeps = atoi(argv[1]);
|
|
|
|
level();
|
|
make_error ("called from main");
|
|
|
|
pthread_create(&ebbr, NULL, brussels_fn, NULL);
|
|
pthread_create(&egll, NULL, london_fn, NULL);
|
|
pthread_create(&zzzz, NULL, petaouchnok_fn, NULL);
|
|
|
|
loopmain = 1;
|
|
while (! (loopt1 && loopt2 && loopmain))
|
|
loopmain++;
|
|
for (i = 0; i < LOOPS; i++) {
|
|
loopmain++;
|
|
|
|
if (loopmain == 10000)
|
|
make_error ("in main loop");
|
|
}
|
|
|
|
pthread_join(ebbr, NULL);
|
|
|
|
make_error ("called from main (the end, before joining t3)");
|
|
|
|
pthread_join(zzzz, NULL);
|
|
|
|
if (argc > 2) {
|
|
for (i = 0; i < 100; i++)
|
|
if ((*(&undef + i*4000) == 0) || (*(&undef - i*4000) == 0)) {
|
|
printf ("there are some null bytes here and there %d\n", i);
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
exit(0);
|
|
}
|