Well you didn't allocate a stack. That mmap needs MAP_STACK
Or, you use the pthread APIs which allocate stacks, for instance pthread_create(). In this case you are calling pthread_attr_setstack(), which has code to re-create the stack allocation with MAP_STACK. Why is that not working? Sebastien Marie <[email protected]> wrote: > On Tue, Dec 01, 2020 at 06:12:32PM +0100, Sebastien Marie wrote: > > Hi, > > > > I have a random segfault while using threads with custom stack. > > sorry, I omitted to mention some elements (thanks deraadt@): > > dmesg contains such lines: > [test-thread]79782/462309 sp=6a5e0e4df18 inside 6a5e0e4d000-6a5e0e4e000: not > MAP_STACK > > the segfault is due to the use of the memory which isn't a stack. > > > In short, I am doing: > > - allocate a stack space for the thread > > - create a thread (with custom stack using pthread_attr_setstack()) > > - join the thread > > - free the allocated stack > > - create a new thread, etc... > > > > If I remove the fact to free the allocate stack once done, it seems > > fine (but reach ENOMEM after a while). > > > > I am suspecting some state corruption or stack reuse, but I can't find > > where for now. Or am I doing bad thing and I shouldn't deallocate the > > stack at his place ? > > > > > > Here a simple reproducer in C: > > > > $ cat test-thread.c > > > > #include <sys/mman.h> > > > > #include <err.h> > > #include <pthread.h> > > #include <stdio.h> > > #include <stdlib.h> > > > > void * > > start(void *arg) > > { > > return arg; > > } > > > > void > > thread_spawn(pthread_t *thread) > > { > > pthread_attr_t attr; > > void *stack; > > > > /* > > * allocate a stack (no need of MAP_STACK: > > * pthread_attr_setstack will set it) > > */ > > stack = mmap(NULL, PTHREAD_STACK_MIN, PROT_READ|PROT_WRITE, > > MAP_PRIVATE|MAP_ANON, -1, 0); > > if (stack == MAP_FAILED) > > err(EXIT_FAILURE, "mmap"); > > > > /* initialize the attr */ > > if (pthread_attr_init(&attr) != 0) > > err(EXIT_FAILURE, "pthread_attr_init"); > > > > if (pthread_attr_setstack(&attr, stack, PTHREAD_STACK_MIN) != 0) > > err(EXIT_FAILURE, "pthread_attr_setstack"); > > > > /* > > * create the thread, and pass the stack address as argument > > * (to retreive it once done) > > */ > > if (pthread_create(thread, &attr, start, stack) != 0) > > err(EXIT_FAILURE, "pthread_create"); > > } > > > > void > > thread_wait(pthread_t *thread) > > { > > void *retval = NULL; > > > > /* join the thread and retreive the stack address */ > > if (pthread_join(*thread, &retval) != 0) > > err(EXIT_FAILURE, "pthread_join"); > > > > /* we are done, unmap the stack address */ > > if (munmap(retval, PTHREAD_STACK_MIN) != 0) > > err(EXIT_FAILURE, "munmap"); > > } > > > > int > > main(int argc, char *argv[]) > > { > > while (1) { > > pthread_t thread; > > > > thread_spawn(&thread); > > thread_wait(&thread); > > } > > > > return EXIT_SUCCESS; > > } > > > > > > $ cc -Wall test-thread.c -lpthread -o test-thread > > $ ./test-thread > > Segmentation fault (core dumped) > > > > > > > > Thanks. > > -- > > Sebastien Marie > > -- > Sebastien Marie >
