Skip to content

Instantly share code, notes, and snippets.

@arnaud-lb
Created July 23, 2023 14:13
Show Gist options
  • Save arnaud-lb/a53eb410b7c26b38fd01eac2cee0467e to your computer and use it in GitHub Desktop.
Save arnaud-lb/a53eb410b7c26b38fd01eac2cee0467e to your computer and use it in GitHub Desktop.
#include <pthread.h>
#include <pthread_np.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <sys/user.h>
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment