darwin,linux: more conservative minimum stack size

uv_thread_create() inspects min(PTHREAD_STACK_MIN, RLIMIT_STACK) to
find out the minimum allowed stack size. After spelunking through
kernel and libc code, I came to the conclusion that allowing such
small stacks does not mix well with signals.

Musl's PTHREAD_STACK_MIN is 2 KB but signal handlers on many
architectures need at least 1 KB to store the signal context,
making it almost impossible to do anything on the thread without
signal delivery overflowing the stack.

Therefore, increase the lower bound to 8 KB. That corresponds to
PTHREAD_STACK_MIN + MINSIGSTKSZ on arm64, which has the largest
MINSIGSTKSZ of the architectures that musl supports.

PR-URL: https://github.com/libuv/libuv/pull/2310
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
Ben Noordhuis 2019-06-07 09:58:49 +02:00
parent abe4f3d58d
commit d89bd156cf

View File

@ -178,6 +178,19 @@ static size_t thread_stack_size(void) {
if (lim.rlim_cur != RLIM_INFINITY) {
/* pthread_attr_setstacksize() expects page-aligned values. */
lim.rlim_cur -= lim.rlim_cur % (rlim_t) getpagesize();
/* Musl's PTHREAD_STACK_MIN is 2 KB on all architectures, which is
* too small to safely receive signals on.
*
* Musl's PTHREAD_STACK_MIN + MINSIGSTKSZ == 8192 on arm64 (which has
* the largest MINSIGSTKSZ of the architectures that musl supports) so
* let's use that as a lower bound.
*
* We use a hardcoded value because PTHREAD_STACK_MIN + MINSIGSTKSZ
* is between 28 and 133 KB when compiling against glibc, depending
* on the architecture.
*/
if (lim.rlim_cur >= 8192)
if (lim.rlim_cur >= PTHREAD_STACK_MIN)
return lim.rlim_cur;
}