Skip to content

bpo-32307: thread: fix stack size on musl platforms. #26224

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ericonr
Copy link

@ericonr ericonr commented May 18, 2021

  • 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.

https://bugs.python.org/issue32307

@the-knights-who-say-ni
Copy link

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept this contribution by verifying everyone involved has signed the PSF contributor agreement (CLA).

Recognized GitHub username

We couldn't find a bugs.python.org (b.p.o) account corresponding to the following GitHub usernames:

@ericonr

This might be simply due to a missing "GitHub Name" entry in one's b.p.o account settings. This is necessary for legal reasons before we can look at this contribution. Please follow the steps outlined in the CPython devguide to rectify this issue.

You can check yourself to see if the CLA has been received.

Thanks again for the contribution, we look forward to reviewing it!

@ericonr
Copy link
Author

ericonr commented May 19, 2021

If desired, I can hardcode glibc to 0, so it always uses the platform default.

@github-actions
Copy link

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale Stale PR or inactive for long period of time. label Jun 19, 2021
@ericonr
Copy link
Author

ericonr commented Jun 19, 2021

Ping, hasn't been reviewed by anyone yet.

* 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.
@Scopetta197
Copy link

ok

@github-actions github-actions bot removed the stale Stale PR or inactive for long period of time. label Jun 20, 2021
#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. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have a unittest in the stdlib that exercises the default recursion limit to on a thread to ensure the process doesn't crash? (it'll be imperfect as different internal call recursion codepaths have different C stack needs, but it still serves as a good failsafe; perhaps have the test raise recursionlimit to 1.5x its default value).

https://github.com/python/cpython/blob/v3.10.0/Lib/test/test_threading.py#L1234 test_threading.test_recursion_limit exists. We should probably change that to raise the recursion limit a bit above the default in it's thread for some safety margin.

#undef THREAD_STACK_SIZE
#define THREAD_STACK_SIZE 0x100000
#endif
#if THREAD_STACK_SIZE == -1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this #if does not look right. it is always undoing and overriding what all of the above #if's have just gone through the platform specific trouble to setup as their own defaults. because they're all testing for == -1

@@ -29,7 +29,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. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to avoid disruption for anyone who may already be supplying CFLAGS containing -DTHREAD_STACK_SIZE=0 in their builds already keep the existing 0 behavior: 0 should be the platform specific values below.

If we want a new value in some circumstances, that should either be enabled via an appropriate test in configure.ac and thus via pyconfig.h. Or yet another platform specific compile time #if check should be used here to detect musl libc.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or yet another platform specific compile time #if check should be used here to detect musl libc.

To be clear, the purpose here is to make the code universal. Right now, the only platform where the default thread size actually works is glibc. Instead of adding a case for each and every platform other than glibc, IMO it makes much more sense to have a sane default and override for one or two platforms as necessary, instead.

Testing for musl is unsupported, they don't provide any identifying macros, by design.

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@gpshead gpshead self-assigned this Oct 4, 2021
@gpshead gpshead removed their assignment May 9, 2022
@gpshead gpshead added DO-NOT-MERGE interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump labels May 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting changes DO-NOT-MERGE interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants