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