Skip to content

Commit 87fc454

Browse files
authored
Fix VM's infinite recursion crash with musl libc (#7558)
* Fix VM's infinite recursion crash with musl libc * Lintfix/cleanup warnings
1 parent a09afab commit 87fc454

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

crates/vm/src/vm/mod.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)