From 0c51afe88efdc11a65b6dd2224b17e7d19cb99ae Mon Sep 17 00:00:00 2001 From: Thomas Wouters Date: Tue, 13 Oct 2026 16:15:56 +0200 Subject: [PATCH 1/3] Extend the use of pthread_getattr_np in stack size detection from any glibc linux to any glibc *or* android linux. --- .../2026-10-13-16-38-00.gh-issue-159320._Yhg1s.rst | 2 ++ Python/ceval.c | 11 +++++++---- 2 files changed, 9 insertions(+), 4 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/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 00000000000000..59eac6cbbf83a1 --- /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 +recrusion. diff --git a/Python/ceval.c b/Python/ceval.c index acf012c44a5305..69329694c43a2e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -142,11 +142,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_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. 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; From f114aa607a7c0da71a981fed65ee0f11e2e3776c Mon Sep 17 00:00:00 2001 From: Thomas Wouters Date: Tue, 13 Oct 2026 23:16:26 +0200 Subject: [PATCH 2/3] Update tests for android's new recursion limit. --- Lib/test/test_ast/test_ast.py | 6 ++---- Lib/test/test_compile.py | 9 +++------ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index bb282eba5d41ee..b1483ad6bf2d40 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -1107,13 +1107,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 53b4be1e75b65a..60886b1a55c16f 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -773,14 +773,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"): @@ -1092,8 +1090,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 From d3516fe34757297f00f4b06a4b1a077f1394b98a Mon Sep 17 00:00:00 2001 From: "T. Wouters" Date: Wed, 14 Oct 2026 13:33:07 +0200 Subject: [PATCH 3/3] Apply batched suggestions from code review Co-authored-by: Malcolm Smith --- .../2026-10-13-16-38-00.gh-issue-159320._Yhg1s.rst | 2 +- Python/ceval.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 index 59eac6cbbf83a1..25e8745ccc02bb 100644 --- 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 @@ -1,2 +1,2 @@ Add dynamic detection of stack sizes on Android, allowing safer deep -recrusion. +recursion. diff --git a/Python/ceval.c b/Python/ceval.c index 69329694c43a2e..43dc48f375301c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -142,7 +142,7 @@ 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 - // musl supports HAVE_PTHRED_GETATTR_NP, but the resulting stack size + // 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,