Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
don't even try to have ucontextes on windows.
[simgrid.git] / tools / cmake / test_prog / prog_stacksetup.c
1 /* Copyright (c) 2010, 2014-2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #if defined OSX
8 #define _XOPEN_SOURCE 700
9 #endif
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #if defined(TEST_sigstack) || defined(TEST_sigaltstack)
15 #include <sys/types.h>
16 #include <signal.h>
17 #include <unistd.h>
18 #endif
19
20 #if defined(TEST_makecontext)
21 #include <ucontext.h>
22 #endif
23
24 union alltypes {
25   long l;
26   double d;
27   void *vp;
28   void (*fp) (void);
29   char *cp;
30 };
31 static volatile char *handler_addr = (char *) 0xDEAD;
32 #if defined(TEST_sigstack) || defined(TEST_sigaltstack)
33 static volatile int handler_done = 0;
34 void handler(int sig)
35 {
36   char garbage[1024];
37   int i;
38   auto int dummy;
39   for (i = 0; i < 1024; i++)
40     garbage[i] = 'X';
41   handler_addr = (char *) &dummy;
42   handler_done = 1;
43   return;
44 }
45 #endif
46 #if defined(TEST_makecontext)
47 static ucontext_t uc_handler;
48 static ucontext_t uc_main;
49 void handler(void)
50 {
51   char garbage[1024];
52   int i;
53   auto int dummy;
54   for (i = 0; i < 1024; i++)
55     garbage[i] = 'X';
56   handler_addr = (char *) &dummy;
57   swapcontext(&uc_handler, &uc_main);
58   return;
59 }
60 #endif
61 int main(int argc, char *argv[])
62 {
63   FILE *f;
64   char *skaddr;
65   char *skbuf;
66   int sksize;
67   char result[1024];
68   int i;
69   sksize = 32768;
70   skbuf = (char *) malloc(sksize * 2 + 2 * sizeof(union alltypes));
71   if (skbuf == NULL)
72     exit(1);
73   for (i = 0; i < sksize * 2 + 2 * sizeof(union alltypes); i++)
74     skbuf[i] = 'A';
75   skaddr = skbuf + sizeof(union alltypes);
76 #if defined(TEST_sigstack) || defined(TEST_sigaltstack)
77   {
78     struct sigaction sa;
79 #if defined(TEST_sigstack)
80     struct sigstack ss;
81 #elif defined(TEST_sigaltstack) && defined(HAVE_STACK_T)
82     stack_t ss;
83 #else
84     struct sigaltstack ss;
85 #endif
86 #if defined(TEST_sigstack)
87     ss.ss_sp = (void *) (skaddr + sksize);
88     ss.ss_onstack = 0;
89     if (sigstack(&ss, NULL) < 0)
90       exit(1);
91 #elif defined(TEST_sigaltstack)
92     ss.ss_sp = (void *) (skaddr + sksize);
93     ss.ss_size = sksize;
94     ss.ss_flags = 0;
95     if (sigaltstack(&ss, NULL) < 0)
96       exit(1);
97 #endif
98     memset((void *) &sa, 0, sizeof(struct sigaction));
99     sa.sa_handler = handler;
100     sa.sa_flags = SA_ONSTACK;
101     sigemptyset(&sa.sa_mask);
102     sigaction(SIGUSR1, &sa, NULL);
103     kill(getpid(), SIGUSR1);
104     while (!handler_done)
105       /*nop */ ;
106   }
107 #endif
108 #if defined(TEST_makecontext)
109   {
110     if (getcontext(&uc_handler) != 0)
111       exit(1);
112     uc_handler.uc_link = NULL;
113     uc_handler.uc_stack.ss_sp = (void *) (skaddr + sksize);
114     uc_handler.uc_stack.ss_size = sksize;
115     uc_handler.uc_stack.ss_flags = 0;
116     makecontext(&uc_handler, handler, 0);
117     swapcontext(&uc_main, &uc_handler);
118   }
119 #endif
120   if (handler_addr == (char *) 0xDEAD)
121     exit(1);
122   if (handler_addr < skaddr + sksize) {
123     /* stack was placed into lower area */
124     if (*(skaddr + sksize) != 'A')
125       sprintf(result, "(skaddr)+(sksize)-%d,(sksize)-%d",
126               sizeof(union alltypes), sizeof(union alltypes));
127     else
128       strcpy(result, "(skaddr)+(sksize),(sksize)");
129   } else {
130     /* stack was placed into higher area */
131     if (*(skaddr + sksize * 2) != 'A')
132       sprintf(result, "(skaddr),(sksize)-%d", sizeof(union alltypes));
133     else
134       strcpy(result, "(skaddr),(sksize)");
135   }
136   if ((f = fopen("conftestval", "w")) == NULL)
137     exit(1);
138   fprintf(f, "%s\n", result);
139   fclose(f);
140   exit(0);
141   return 1;
142 }