This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: nptl stack size


Matthieu CASTET a écrit :
Hi,

after looking at how nptl allocate stack I am a bit confused.
It seems that for nptl the stacksize attribute is the size of the stack
+ the size of the guard + the size of the thread descriptor [1].
This can be see by strace [2]. We allocate 16K with mmap, we use 4K for
the guard and 0x4039f000+16384-0x403a1fe8 for some thread descriptor
data. There is less than 8K for the application

But when looking to posix specification, I understand that
pthread_attr_setstacksize set the stack for the application and that the
guard size is extra memory [3].

Why nptl doesn't allocate extra stack size for that ?

I attach a small testcase.

It output [1].
It show that the guardsize is allocated on the stack.
For me it violate posix assertion "the implementation allocates extra memory at the overflow end of the stack as a buffer against stack overflow of the stack pointer".
Also it show the thread have a smaller stack than stacksize. It seems to violate posix "The stacksize attribute shall define the minimum stack size (in bytes) ".



Does somebody know why nptl implementation does that ?


Matthieu

[1]
default stack and guard size
stacksize 8388608, guardsize 4096
creating thread 0x80486d4
done with status 0 Success
stack start at 0xb7e713d4
small stack size
stacksize 16384, guardsize 4096
creating thread 0x80486d4
done with status 0 Success
stack start at 0xb7fdc3d4
trying to set a guardsize bigger than the stacksize
the implementation allocates extra memory at the overflow end of the stack as a buffer against stack overflow of the stack pointer
stacksize 16384, guardsize 16384
creating thread 0x80486d4
done with status 22 Invalid argument
default stack size and guard size like previous test
stacksize 8388608, guardsize 16384
creating thread 0x80486d4
done with status 0 Success
stack start at 0xb7e713d4
doing allocation on the stack with default stack size
stacksize 8388608, guardsize 4096
creating thread 0x80486df
done with status 0 Success
stack start at 0xb7e6d438
trying to use near all the stack
The stacksize attribute shall define the minimum stack size (in bytes) allocated for the created threads stack.
stacksize 16384, guardsize 4096
creating thread 0x80486df
Erreur de segmentation
#include <pthread.h>
#include <assert.h>
#include <limits.h>
#include <stdio.h>


#define CHECK(x) do { \
		assert(x==0); \
	} while (0)
void *dummy(void *data)
{
	int stack;
	return &stack;
}

void *allocstack(void *data)
{
	char dumy[PTHREAD_STACK_MIN-100];
	/* don't use memset to know the stack usage */
	int i;
	for (i = 0; i < sizeof(dumy); i++)
		dumy[i] = 0;
	return dumy;
}


void launch_thread(pthread_attr_t *attr, void *(*start_routine)(void *))
{
	size_t guardsize;
	size_t stacksize;
	pthread_t thandle;
	void *ret;
	int res;

	CHECK(pthread_attr_getguardsize(attr, &guardsize));
	CHECK(pthread_attr_getstacksize(attr, &stacksize));

	printf("stacksize %d, guardsize %d\n", stacksize, guardsize);

	printf("creating thread %p\n", start_routine);
	res = pthread_create(&thandle, attr, start_routine, NULL);
	printf("done with status %d %s\n", res, strerror(res));
	if (res == 0) {
		CHECK(pthread_join(thandle, &ret));
		printf("stack start at %p\n", ret);
	}
}
int main()
{
	pthread_attr_t attr;
	int ret;

	CHECK(pthread_attr_init(&attr));

	printf("default stack and guard size\n");
	launch_thread(&attr, dummy);

	printf("small stack size\n");
	CHECK(pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN));
	launch_thread(&attr, dummy);

	printf("trying to set a guardsize bigger than the stacksize\n");
	/* http://www.opengroup.org/onlinepubs/009695399/functions/pthread_attr_getguardsize.html */
	printf("the implementation allocates extra memory at the overflow end of the stack as a buffer against stack overflow of the stack pointer\n");
	CHECK(pthread_attr_setguardsize(&attr, PTHREAD_STACK_MIN));
	launch_thread(&attr, dummy);

	CHECK(pthread_attr_destroy(&attr));
	CHECK(pthread_attr_init(&attr));
	printf("default stack size and guard size like previous test\n");
	CHECK(pthread_attr_setguardsize(&attr, PTHREAD_STACK_MIN));
	launch_thread(&attr, dummy);

	CHECK(pthread_attr_destroy(&attr));
	CHECK(pthread_attr_init(&attr));
	printf("doing allocation on the stack with default stack size\n");
	launch_thread(&attr, allocstack);

	CHECK(pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN));
	printf("trying to use near all the stack\n");
	/* http://www.opengroup.org/onlinepubs/009695399/functions/pthread_attr_getstacksize.html */
	printf("The stacksize attribute shall define the minimum stack size (in bytes) allocated for the created threads stack.\n");
	launch_thread(&attr, allocstack);
	return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]