#include #include #include #include #include #include #include #include #include #include int pipefds[2]; int (*volatile use_all_stack_fun)(void *limit); void* (*volatile frame_addr_fun)(void); static void* frame_addr() { return __builtin_frame_address(0); } static int use_all_stack(void *limit) { if (frame_addr_fun() < limit) { return 1; } return 1 + use_all_stack_fun(limit); } void *start_routine(void *arg) { pthread_attr_t attr; pthread_attr_init(&attr); void *addr; size_t size; size_t guardsize; use_all_stack_fun = use_all_stack; frame_addr_fun = frame_addr; if (pthread_attr_get_np(pthread_self(), &attr)) { perror("attr_get_np"); exit(1); } if (pthread_attr_getstack(&attr, &addr, &size)) { perror("getstack"); exit(1); } if (pthread_attr_getguardsize(&attr, &guardsize)) { perror("getguardsize"); exit(1); } /* Checking that we can actually use stack from addr+size to addr+size */ void *limit = (char*)addr + 256; int recur_depth = use_all_stack(limit); fprintf(stderr, "Thread %zd: stack low: %p; high: %p; size: %zd\n" " guardsize: %zd (%p->%p)\n" " frame addr: %p; (%zd from high)\n" " recursion depth: %d\n", (uintptr_t) arg, addr, (char*)addr+size, size, guardsize, (char*)addr-guardsize, addr, frame_addr(), (size_t)((char*)addr+size-(uintptr_t)frame_addr()), recur_depth); write(pipefds[1], ".", 1); char c; read(pipefds[1], &c, 1); fprintf(stderr, "Thread done"); return NULL; } int main() { pthread_t t1, t2, t3; pthread_attr_t attr1, attr2, attr3; if (pipe(pipefds)) { perror("pipe"); exit(1); } pthread_attr_init(&attr1); if (pthread_create(&t1, &attr1, &start_routine, (void*)1)) { perror("pthread_create(t1)"); exit(1); } pthread_attr_init(&attr2); pthread_attr_setguardsize(&attr2, 1*1024*1024); pthread_create(&t2, &attr2, start_routine, (void*)2); pthread_attr_init(&attr3); pthread_attr_setguardsize(&attr3, 16*1024*1024); pthread_create(&t3, &attr3, start_routine, (void*)3); for (int i = 0; i < 3; i++) { char c; if (read(pipefds[0], &c, 1) != 1) { perror("read"); exit(1); } } char buf[4096]; sprintf(buf, "procstat vm %d >&2", getpid()); system(buf); return 0; }