@@ -94,7 +94,7 @@ pub struct VirtualMachine {
9494 pub initialized : bool ,
9595 recursion_depth : Cell < usize > ,
9696 /// C stack soft limit for detecting stack overflow (like c_stack_soft_limit)
97- #[ cfg_attr( miri, allow( dead_code) ) ]
97+ #[ cfg_attr( any ( miri, target_env = "musl" ) , allow( dead_code) ) ]
9898 c_stack_soft_limit : Cell < usize > ,
9999 /// Async generator firstiter hook (per-thread, set via sys.set_asyncgen_hooks)
100100 pub async_gen_firstiter : RefCell < Option < PyObjectRef > > ,
@@ -1424,12 +1424,12 @@ impl VirtualMachine {
14241424
14251425 /// Stack margin bytes (like _PyOS_STACK_MARGIN_BYTES).
14261426 /// 2048 * sizeof(void*) = 16KB for 64-bit.
1427- #[ cfg_attr( miri, allow( dead_code) ) ]
1427+ #[ cfg_attr( any ( miri, target_env = "musl" ) , allow( dead_code) ) ]
14281428 const STACK_MARGIN_BYTES : usize = 2048 * core:: mem:: size_of :: < usize > ( ) ;
14291429
14301430 /// Get the stack boundaries using platform-specific APIs.
14311431 /// Returns (base, top) where base is the lowest address and top is the highest.
1432- #[ cfg( all( not( miri) , windows) ) ]
1432+ #[ cfg( all( not( miri) , not ( target_env = "musl" ) , windows) ) ]
14331433 fn get_stack_bounds ( ) -> ( usize , usize ) {
14341434 use windows_sys:: Win32 :: System :: Threading :: {
14351435 GetCurrentThreadStackLimits , SetThreadStackGuarantee ,
@@ -1448,7 +1448,7 @@ impl VirtualMachine {
14481448
14491449 /// Get stack boundaries on non-Windows platforms.
14501450 /// Falls back to estimating based on current stack pointer.
1451- #[ cfg( all( not( miri) , not( windows) ) ) ]
1451+ #[ cfg( all( not( miri) , not( target_env = "musl" ) , not ( windows) ) ) ]
14521452 fn get_stack_bounds ( ) -> ( usize , usize ) {
14531453 // Use pthread_attr_getstack on platforms that support it
14541454 #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
@@ -1499,35 +1499,35 @@ impl VirtualMachine {
14991499
15001500 /// Calculate the C stack soft limit based on actual stack boundaries.
15011501 /// soft_limit = base + 2 * margin (for downward-growing stacks)
1502- #[ cfg( not( miri) ) ]
1502+ #[ cfg( all ( not( miri) , not ( target_env = "musl" ) ) ) ]
15031503 fn calculate_c_stack_soft_limit ( ) -> usize {
15041504 let ( base, _top) = Self :: get_stack_bounds ( ) ;
1505- // Soft limit is 2 margins above the base
15061505 base + Self :: STACK_MARGIN_BYTES * 2
15071506 }
15081507
1509- /// Miri doesn't support inline assembly, so disable C stack checking.
1510- #[ cfg( miri) ]
1508+ /// Musl currently reports stack bounds in a way that trips the VM's
1509+ /// native stack guard during frozen stdlib bootstrap, so keep the Python
1510+ /// recursion limit as the only guard there.
1511+ #[ cfg( any( miri, target_env = "musl" ) ) ]
15111512 fn calculate_c_stack_soft_limit ( ) -> usize {
15121513 0
15131514 }
15141515
15151516 /// Check if we're near the C stack limit (like _Py_MakeRecCheck).
15161517 /// Returns true only when stack pointer is in the "danger zone" between
15171518 /// soft_limit and hard_limit (soft_limit - 2*margin).
1518- #[ cfg( not( miri) ) ]
1519+ #[ cfg( all ( not( miri) , not ( target_env = "musl" ) ) ) ]
15191520 #[ inline( always) ]
15201521 fn check_c_stack_overflow ( & self ) -> bool {
15211522 let current_sp = psm:: stack_pointer ( ) as usize ;
15221523 let soft_limit = self . c_stack_soft_limit . get ( ) ;
1523- // Stack grows downward: check if we're below soft limit but above hard limit
1524- // This matches CPython's _Py_MakeRecCheck behavior
15251524 current_sp < soft_limit
15261525 && current_sp >= soft_limit. saturating_sub ( Self :: STACK_MARGIN_BYTES * 2 )
15271526 }
15281527
1529- /// Miri doesn't support inline assembly, so always return false.
1530- #[ cfg( miri) ]
1528+ /// Miri does not support the native stack probe, and musl currently trips
1529+ /// the probe during stdlib bootstrap.
1530+ #[ cfg( any( miri, target_env = "musl" ) ) ]
15311531 #[ inline( always) ]
15321532 fn check_c_stack_overflow ( & self ) -> bool {
15331533 false
0 commit comments