From 1a2f2496726b11621936ba19c67c9e8c9a8bb486 Mon Sep 17 00:00:00 2001 From: "T. Wouters" Date: Wed, 14 Oct 2026 14:11:01 +0200 Subject: [PATCH] gh-159320: Enable stack size detection on Android (GH-159321) Extend the use of pthread_getattr_np in stack size detection from any glibc linux to any glibc *or* android linux. Update tests for android's new recursion limit. (cherry picked from commit 8ff41c2ae723a62abace675b058dd4da8f90a397) Co-authored-by: T. Wouters Co-authored-by: Malcolm Smith --- Lib/test/test_ast/test_ast.py | 6 ++---- Lib/test/test_compile.py | 9 +++------ .../2026-10-13-16-38-00.gh-issue-159320._Yhg1s.rst | 2 ++ Python/ceval.c | 11 +++++++---- 4 files changed, 14 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-10-13-16-38-00.gh-issue-159320._Yhg1s.rst diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 19e34457c89ac5a..faafd98b5d5f96d 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -1056,13 +1056,11 @@ def next(self): enum._test_simple_enum(_Precedence, _ast_unparse._Precedence) @support.cpython_only - @support.run_with_limited_c_stack( - 100_000 if sys.platform == "android" else 500_000) + @support.run_with_limited_c_stack(500_000) @skip_wasi_stack_overflow() @skip_emscripten_stack_overflow() def test_ast_recursion_limit(self): - # Android test devices have less memory. - crash_depth = 100_000 if sys.platform == "android" else 500_000 + crash_depth = 500_000 success_depth = 200 if _testinternalcapi is not None: remaining = _testinternalcapi.get_c_recursion_remaining() diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 6e997c72fc0f05c..489d293c15383af 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -724,14 +724,12 @@ def test_yet_more_evil_still_undecodable(self): @support.cpython_only @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") - @support.run_with_limited_c_stack( - 100_000 if sys.platform == "android" else 500_000) + @support.run_with_limited_c_stack(500_000) @support.skip_emscripten_stack_overflow() def test_compiler_recursion_limit(self): # Compiler frames are small limit = 100 - # Android test devices have less memory. - crash_depth = limit * (1000 if sys.platform == "android" else 5000) + crash_depth = limit * 5000 success_depth = limit def check_limit(prefix, repeated, mode="single"): @@ -1043,8 +1041,7 @@ def test_path_like_objects(self): # complex statements. @support.requires_resource('cpu') def test_stack_overflow(self): - # Android test devices have less memory. - size = 100_000 if sys.platform == "android" else 200_000 + size = 200_000 compile("if a: b\n" * size, "", "exec") # Multiple users rely on the fact that CPython does not generate diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-13-16-38-00.gh-issue-159320._Yhg1s.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-13-16-38-00.gh-issue-159320._Yhg1s.rst new file mode 100644 index 000000000000000..25e8745ccc02bb0 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-13-16-38-00.gh-issue-159320._Yhg1s.rst @@ -0,0 +1,2 @@ +Add dynamic detection of stack sizes on Android, allowing safer deep +recursion. diff --git a/Python/ceval.c b/Python/ceval.c index bf2d0a87909cc9e..b132f9ba8331dcd 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -154,11 +154,14 @@ hardware_stack_limits(uintptr_t *base, uintptr_t *top, uintptr_t sp) *top = (uintptr_t)stack_addr; *base = ((uintptr_t)stack_addr) - stack_size; #else - /// XXX musl supports HAVE_PTHRED_GETATTR_NP, but the resulting stack size - /// (on alpine at least) is much smaller than expected and imposes undue limits - /// compared to the old stack size estimation. (We assume musl is not glibc.) + // musl supports HAVE_PTHREAD_GETATTR_NP, but the resulting stack size + // (on alpine at least) is much smaller than expected and imposes undue + // limits compared to the old stack size estimation. musl doesn't give + // us a way to detect it, so we have to assume any non-glibc, + // non-Android Linux is musl and mustn't rely on pthread_getattr_np. # if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(_AIX) && \ - !defined(__NetBSD__) && (defined(__GLIBC__) || !defined(__linux__)) + !defined(__NetBSD__) && \ + (defined(__GLIBC__) || defined(__ANDROID__) || !defined(__linux__)) size_t stack_size, guard_size; void *stack_addr; pthread_attr_t attr;