From fc204228484b759b7abbc01b3a13b6371eee367a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Nogueira?= Date: Tue, 18 May 2021 20:21:02 -0300 Subject: [PATCH] bpo-32307: thread: fix stack size on musl platforms. * issue32307: Bad assumption on thread stack size makes python crash with musl libc Python/thread_pthread.h hardcodes "known good" thread stack sizes for several platforms it knows about, and assumes all other platforms will follow glibc's behavior of allocating big enough thread stacks. Instead, we force a default value of 2MB (much bigger than musl's 128kB default) which should be safe on most platforms, and override it for the specific platforms which need even more (or less, as in vxworks's case). This also allows us to remove AIX's special case, since it now matches the default. Instead of hardcoding yet more values here, users should be encouraged to set their own using CFLAGS. Alternatively, they can set THREAD_STACK_SIZE to 0 and use the platform's default. This way, test_threading no longer crashes on musl systems. Since we are here, it is not necessary to check if THREAD_STACK_SIZE is defined in this part of the header, because the first few lines after '#ifdef _POSIX_THREAD_ATTR_STACKSIZE' ensure it's always defined. --- .../2021-06-19-18-04-47.bpo-32307.V1wzBY.rst | 4 ++++ Python/thread_pthread.h | 20 +++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2021-06-19-18-04-47.bpo-32307.V1wzBY.rst diff --git a/Misc/NEWS.d/next/Build/2021-06-19-18-04-47.bpo-32307.V1wzBY.rst b/Misc/NEWS.d/next/Build/2021-06-19-18-04-47.bpo-32307.V1wzBY.rst new file mode 100644 index 00000000000000..d767051b9f8a0a --- /dev/null +++ b/Misc/NEWS.d/next/Build/2021-06-19-18-04-47.bpo-32307.V1wzBY.rst @@ -0,0 +1,4 @@ +Force a default thread stack size value for all platforms instead of +assuming that they all have enough for Python threads. This makes it so too +many recursions are caught by the interpreter instead of stack overflowing +on musl libc. diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index e660bca8406860..bec8e9b20f8c77 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -40,7 +40,9 @@ be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */ #ifdef _POSIX_THREAD_ATTR_STACKSIZE #ifndef THREAD_STACK_SIZE -#define THREAD_STACK_SIZE 0 /* use default stack size */ +/* -1 means THREAD_STACK_SIZE hasn't been given a proper value yet. + -DTHREAD_STACK_SIZE=0 in CFLAGS will force the platform's default instead. */ +#define THREAD_STACK_SIZE -1 #endif /* The default stack size for new threads on BSD is small enough that @@ -54,28 +56,30 @@ * as it also depends on the other configure options like chosen sanitizer * runtimes. */ -#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 +#if defined(__FreeBSD__) && THREAD_STACK_SIZE == -1 #undef THREAD_STACK_SIZE #define THREAD_STACK_SIZE 0x400000 #endif -#if defined(_AIX) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 -#undef THREAD_STACK_SIZE -#define THREAD_STACK_SIZE 0x200000 -#endif /* bpo-38852: test_threading.test_recursion_limit() checks that 1000 recursive Python calls (default recursion limit) doesn't crash, but raise a regular RecursionError exception. In debug mode, Python function calls allocates more memory on the stack, so use a stack of 8 MiB. */ -#if defined(__ANDROID__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 +#if defined(__ANDROID__) && THREAD_STACK_SIZE == -1 # ifdef Py_DEBUG # undef THREAD_STACK_SIZE # define THREAD_STACK_SIZE 0x800000 # endif #endif -#if defined(__VXWORKS__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 +#if defined(__VXWORKS__) && THREAD_STACK_SIZE == -1 #undef THREAD_STACK_SIZE #define THREAD_STACK_SIZE 0x100000 #endif +#if THREAD_STACK_SIZE == -1 +#undef THREAD_STACK_SIZE +/* This is big enough for most platforms without being wasteful. */ +#define THREAD_STACK_SIZE 0x200000 +#endif + /* for safety, ensure a viable minimum stacksize */ #define THREAD_STACK_MIN 0x8000 /* 32 KiB */ #else /* !_POSIX_THREAD_ATTR_STACKSIZE */