• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <ucontext.h>
4 #include "tests/sys_mman.h"
5 
6 #include "valgrind.h"
7 
8 #define STACK_SIZE (10 * 4096)
9 
10 // This test is checking the libc context calls (setcontext, etc.) and
11 // checks that Valgrind notices their stack changes properly.
12 
13 typedef  struct ucontext  mycontext;
14 
15 mycontext ctx1, ctx2, oldc;
16 int count;
17 
hello(mycontext * newc)18 void hello(mycontext *newc)
19 {
20     printf("hello, world: %d\n", count);
21     if (count++ == 2)
22         newc = &oldc;
23     setcontext(newc);
24 }
25 
init_context(mycontext * uc)26 int init_context(mycontext *uc)
27 {
28     void *stack;
29     int ret;
30 
31     if (getcontext(uc) == -1) {
32         //perror("getcontext");
33         printf("getcontext() doesn't seem to work\n");
34         exit(1);
35     }
36 
37     stack = (void *)mmap(0, STACK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC,
38                                         MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
39 
40     if (stack == (void*)-1) {
41         perror("mmap");
42         exit(1);
43     }
44 
45     ret = VALGRIND_STACK_REGISTER(stack, stack + STACK_SIZE);
46 
47     uc->uc_link = NULL;
48     uc->uc_stack.ss_sp = stack;
49     uc->uc_stack.ss_size = STACK_SIZE;
50     uc->uc_stack.ss_flags = 0;
51 
52     return ret;
53 }
54 
main(int argc,char ** argv)55 int main(int argc, char **argv)
56 {
57     int c1 = init_context(&ctx1);
58     int c2 = init_context(&ctx2);
59 
60     makecontext(&ctx1, (void (*)()) hello, 1, &ctx2);
61     makecontext(&ctx2, (void (*)()) hello, 1, &ctx1);
62 
63     swapcontext(&oldc, &ctx1);
64 
65     VALGRIND_STACK_DEREGISTER(c1);
66     //free(ctx1.uc_stack.ss_sp);
67     VALGRIND_STACK_DEREGISTER(c2);
68     //free(ctx2.uc_stack.ss_sp);
69 
70     return 0;
71 }
72