Skip to content

Stack overflow test errors in Alpine after GH-130398 #131338

Description

@bitdancer

Bug report

Bug description:

After GH-130398 (0142236) was applied, test.test_dynamic.RebindBuiltinsTests.test_load_global_specialization_failure_keeps_oparg and test.test_functools.TestLRUC.test_lru_recursion fail with RecursionError: Stack overflow (used 96 kB) while calling a Python object on Alpine linux with python compiled with musl.

I don't know the significance of this; the tests were already skipped on wasi and/or emscripten before that commit, which also use musl. However, the fact that a stack overflow happens where one did not previously happen is worrisome for the stability of python on Alpine.

Let me know if there is any debugging assistance I can provide.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Other

Linked PRs

Activity

  1. bitdancer commented on Mar 16, 2025

    @bitdancer
    MemberAuthor
  2. added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    3.14bugs and security fixes
    on Mar 16, 2025
  3. markshannon commented on Mar 17, 2025

    @markshannon
    Member

    If it is anything like the emscrpiten issue, then it might be that musl libc claims to support pthread_getattr_np, but does not actually support it.

    Is HAVE_PTHREAD_GETATTR_NP defined and if it is, does pthread_getattr_np give sensible stack values?

  4. bitdancer commented on Mar 19, 2025

    @bitdancer
    MemberAuthor

    Alpine musl does indeed have pthread_getattr_np, and claims to support it as of 0.9.10 ;) (http://git.musl-libc.org/cgit/musl/tree/src/thread/pthread_getattr_np.c).

    Putting

        printf("guard_size %lu\n", guard_size);
        printf("stack_size %lu\n", stack_size);
    

    in ceval.c gives me:

    guard_size 0
    stack_size 126976
    

    but I have no context to know if that is "sensible" or not ;) If it means anything, the stack_size between runs of python -m unittest test.test_functools.TestLRUC.test_lru_recursion varies between three values, the above and 135168 and 131072.

    In 3.13 alpine-musl python can handle fib calls up to what would at the time of call exceed sys.getrecursionlimit (1000), but on master it caps out at less than 100 (which is what triggers the lru test failure). So I'm guessing that means the above number is "not sensible" ;)

    I don't know enough about this subject to know if/what to report to musl about this, but I definitely would not like to see 3.14 going out the door with a recursion-hobbled python on Alpine. Note that I'm planning to volunteer to be tier3 support for alpine (x86_64-linux-musl) once I can get the tests passing on the buildbot one way or another (and I can set up my own buildbot if needed).

  5. bitdancer commented on May 20, 2025

    @bitdancer
    MemberAuthor

    Others have encountered this problem with Alpine/MUSL reporting a small stack size via pthread_getattr_np.

    As things stand, if we change the test so we can see the recursion error message, we get:

    RecursionError: Stack overflow (used 96 kB) while calling a Python object
    

    If this code is disabled for Alpine/MUSL, we instead get:

    RecursionError: Stack overflow (used 3907 kB) while calling a Python object
    
  6. bitdancer commented on May 20, 2025

    @bitdancer
    MemberAuthor

    I've proposed a PR to only enable this for GLIBC, where we know it works. It seems like it would be better to only enable it for those platforms where we know it works, if there are others.

  7. bitdancer commented on May 26, 2025

    @bitdancer
    MemberAuthor

    Note; although someone applied the unsupported platform tag, I have learned that this does also affect at least emscripten, which is supported. I think emscripten crafted a local hack to get around it, but it seems to me to be better to make this opt-in to reduce the chance of future problems.

    @hugovk I think this should be addressed one way or another before the release candidates.

  8. bitdancer commented on Jun 15, 2025

    @bitdancer
    MemberAuthor

    For the record, I found the following documentation:


    Thread stack size

    The default stack size for new threads on glibc is determined based on the resource limit governing the main thread’s stack (RLIMIT_STACK). It generally ends up being 2-10 MB.

    musl provides a default thread stack size of 128k (80k prior to 1.1.21). This does not include the guard page, nor does it include the space used for TLS unless total TLS size is very small. So the actual map size may appear closer to 1400k, with around 128k usable by the application. This size was determined empirically with the goals of not gratuitously breaking applications but also not causing large amounts of memory and virtual address space to be committed in programs with large numbers of threads. Programs needing larger stacks, or which explicitly want a smaller stack, should make this explicit with pthread_attr_setstacksize. For largely unrestrained use of the standard library, a minimum of 12k is recommended, but stack sizes down to 2k are allowed.

    Since 1.1.21, musl supports increasing the default thread stack size via the PT_GNU_STACK program header, which can be set at link time via -Wl,-z,stack-size=N.


    This makes both the 90K result with the new code and the 3907K result with the old code seem incorrect :(

  9. ngoldbaum commented on Jun 22, 2025

    @ngoldbaum
    Contributor

    We saw some real-world crashes on free-threaded musllinux builds for libcst: #131338

  10. ngoldbaum commented on Jun 22, 2025

    @ngoldbaum
    Contributor

    (not sure if those crashes are the same issue)

  11. ngoldbaum commented on Jun 22, 2025

    @ngoldbaum
    Contributor

    Also some unexplained crashes in SciPy: scipy/scipy#23187 (comment)

  12. zsol commented on Jun 25, 2025

    @zsol
    Member

    We saw some real-world crashes on free-threaded musllinux builds for libcst: #131338

    The correct issue for this is Instagram/LibCST#1362 :)

  13. ngoldbaum commented on Jul 25, 2025

    @ngoldbaum
    Contributor

    I still see the segfault on Python 3.14, with a possible fix applied: #134336 (comment).

    I wish I had any ideas for how to debug this further.

  14. added a commit that references this issue on Jul 28, 2025
  15. added a commit that references this issue on Jul 28, 2025
  16. added a commit that references this issue on Aug 10, 2025
  17. added a commit that references this issue on Aug 19, 2025
  18. added a commit that references this issue on Sep 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.14bugs and security fixesOS-unsupportedinterpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions