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
> 

Reply via email to