Home | History | Annotate | Download | only in linux
      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 
     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 
     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 
     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