Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
apply review
  • Loading branch information
youknowone committed Dec 11, 2025
commit cf3ad0adafa07421d3909913eaca750a52cf8f69
88 changes: 32 additions & 56 deletions crates/stdlib/src/faulthandler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,74 +31,50 @@ mod decl {
previous: libc::sighandler_t,
}

#[cfg(unix)]
impl FaultHandler {
const fn new(signum: libc::c_int, name: &'static str) -> Self {
Self {
signum,
enabled: false,
name,
// SAFETY: sigaction is a C struct that can be zero-initialized
previous: unsafe { std::mem::zeroed() },
}
}
}

#[cfg(windows)]
impl FaultHandler {
const fn new(signum: libc::c_int, name: &'static str) -> Self {
Self {
signum,
enabled: false,
name,
previous: 0,
}
}
}

/// faulthandler_handlers[]
/// Number of fatal signals
#[cfg(unix)]
const FAULTHANDLER_NSIGNALS: usize = 5;
#[cfg(windows)]
const FAULTHANDLER_NSIGNALS: usize = 3;
const FAULTHANDLER_NSIGNALS: usize = 4;

// CPython uses static arrays for signal handlers which requires mutable static access.
// This is safe because:
// 1. Signal handlers run in a single-threaded context (from the OS perspective)
// 2. FAULTHANDLER_HANDLERS is only modified during enable/disable operations
// 3. This matches CPython's faulthandler.c implementation
#[cfg(unix)]
static mut FAULTHANDLER_HANDLERS: [FaultHandler; FAULTHANDLER_NSIGNALS] = unsafe {
[
FaultHandler {
signum: libc::SIGBUS,
enabled: false,
name: "Bus error",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGILL,
enabled: false,
name: "Illegal instruction",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGFPE,
enabled: false,
name: "Floating-point exception",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGABRT,
enabled: false,
name: "Aborted",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGSEGV,
enabled: false,
name: "Segmentation fault",
previous: std::mem::zeroed(),
},
]
};

#[cfg(windows)]
static mut FAULTHANDLER_HANDLERS: [FaultHandler; FAULTHANDLER_NSIGNALS] = [
FaultHandler {
signum: libc::SIGFPE,
enabled: false,
name: "Floating-point exception",
previous: 0,
},
FaultHandler {
signum: libc::SIGABRT,
enabled: false,
name: "Aborted",
previous: 0,
},
FaultHandler {
signum: libc::SIGSEGV,
enabled: false,
name: "Segmentation fault",
previous: 0,
},
#[cfg(unix)]
FaultHandler::new(libc::SIGBUS, "Bus error"),
FaultHandler::new(libc::SIGILL, "Illegal instruction"),
FaultHandler::new(libc::SIGFPE, "Floating-point exception"),
FaultHandler::new(libc::SIGABRT, "Aborted"),
FaultHandler::new(libc::SIGSEGV, "Segmentation fault"),
];
Comment on lines +59 to +78
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I was workshopping this on my own, prior to #6400, I came up with something similar to this, finding out from the libc repository that SIGILL does exist on Windows. Would this work?

Suggested change
/// faulthandler_handlers[]
/// Number of fatal signals
#[cfg(unix)]
const FAULTHANDLER_NSIGNALS: usize = 5;
#[cfg(windows)]
const FAULTHANDLER_NSIGNALS: usize = 3;
// CPython uses static arrays for signal handlers which requires mutable static access.
// This is safe because:
// 1. Signal handlers run in a single-threaded context (from the OS perspective)
// 2. FAULTHANDLER_HANDLERS is only modified during enable/disable operations
// 3. This matches CPython's faulthandler.c implementation
#[allow(static_mut_refs)]
#[cfg(unix)]
static mut FAULTHANDLER_HANDLERS: [FaultHandler; FAULTHANDLER_NSIGNALS] = unsafe {
[
FaultHandler {
signum: libc::SIGBUS,
enabled: false,
name: "Bus error",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGILL,
enabled: false,
name: "Illegal instruction",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGFPE,
enabled: false,
name: "Floating-point exception",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGABRT,
enabled: false,
name: "Aborted",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGSEGV,
enabled: false,
name: "Segmentation fault",
previous: std::mem::zeroed(),
},
]
};
#[allow(static_mut_refs)]
#[cfg(windows)]
static mut FAULTHANDLER_HANDLERS: [FaultHandler; FAULTHANDLER_NSIGNALS] = [
FaultHandler {
signum: libc::SIGFPE,
enabled: false,
name: "Floating-point exception",
previous: 0,
},
FaultHandler {
signum: libc::SIGABRT,
enabled: false,
name: "Aborted",
previous: 0,
},
FaultHandler {
signum: libc::SIGSEGV,
enabled: false,
name: "Segmentation fault",
previous: 0,
},
];
// CPython uses static arrays for signal handlers which requires mutable static access.
// This is safe because:
// 1. Signal handlers run in a single-threaded context (from the OS perspective)
// 2. FAULTHANDLER_HANDLERS is only modified during enable/disable operations
// 3. This matches CPython's faulthandler.c implementation
#[allow(static_mut_refs)]
static mut FAULTHANDLER_HANDLERS: [FaultHandler; if cfg!(unix) {5} else {4}] = unsafe {
[
#[cfg(unix)]
FaultHandler {
signum: libc::SIGBUS,
enabled: false,
name: "Bus error",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGILL,
enabled: false,
name: "Illegal instruction",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGFPE,
enabled: false,
name: "Floating-point exception",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGABRT,
enabled: false,
name: "Aborted",
previous: std::mem::zeroed(),
},
FaultHandler {
signum: libc::SIGSEGV,
enabled: false,
name: "Segmentation fault",
previous: std::mem::zeroed(),
},
]
};
/// faulthandler_handlers[]
/// Number of fatal signals
const FAULTHANDLER_NSIGNALS: usize = FAULTHANDLER_HANDLERS.len();

You might also want a FaultHandler::default() implementation to same some repetition in the future.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! applied it


/// fatal_error state
Expand Down
Loading