Auto merge of #138831 - matthiaskrgr:rollup-3t0dqiz, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #138609 (Add stack overflow handler for cygwin) - #138639 (Clean UI tests 2 of n) - #138773 (catch_unwind intrinsic: document return value) - #138782 (test(ui): add tuple-struct-where-clause-suggestion ui test for #91520) - #138794 (expand: Do not report `cfg_attr` traces on macros as unused attributes) - #138801 (triagebot: add autolabel rules for D-* and L-*) - #138804 (Allow inlining for `Atomic*::from_ptr`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b48576b4db
17 changed files with 226 additions and 86 deletions
|
@ -3002,6 +3002,7 @@ pub const fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discrimina
|
|||
|
||||
/// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the
|
||||
/// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs.
|
||||
/// Returns `1` if unwinding occurred and `catch_fn` was called; returns `0` otherwise.
|
||||
///
|
||||
/// `catch_fn` must not unwind.
|
||||
///
|
||||
|
|
|
@ -469,6 +469,7 @@ impl AtomicBool {
|
|||
///
|
||||
/// [valid]: crate::ptr#safety
|
||||
/// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
|
||||
#[inline]
|
||||
#[stable(feature = "atomic_from_ptr", since = "1.75.0")]
|
||||
#[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
|
||||
pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool {
|
||||
|
@ -1389,6 +1390,7 @@ impl<T> AtomicPtr<T> {
|
|||
///
|
||||
/// [valid]: crate::ptr#safety
|
||||
/// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
|
||||
#[inline]
|
||||
#[stable(feature = "atomic_from_ptr", since = "1.75.0")]
|
||||
#[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
|
||||
pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T> {
|
||||
|
@ -2525,6 +2527,7 @@ macro_rules! atomic_int {
|
|||
///
|
||||
/// [valid]: crate::ptr#safety
|
||||
/// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
|
||||
#[inline]
|
||||
#[stable(feature = "atomic_from_ptr", since = "1.75.0")]
|
||||
#[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
|
||||
pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a $atomic_type {
|
||||
|
|
|
@ -585,6 +585,7 @@ mod imp {
|
|||
target_os = "openbsd",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "cygwin",
|
||||
)))]
|
||||
mod imp {
|
||||
pub unsafe fn init() {}
|
||||
|
@ -597,3 +598,89 @@ mod imp {
|
|||
|
||||
pub unsafe fn drop_handler(_data: *mut libc::c_void) {}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "cygwin")]
|
||||
mod imp {
|
||||
mod c {
|
||||
pub type PVECTORED_EXCEPTION_HANDLER =
|
||||
Option<unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32>;
|
||||
pub type NTSTATUS = i32;
|
||||
pub type BOOL = i32;
|
||||
|
||||
unsafe extern "system" {
|
||||
pub fn AddVectoredExceptionHandler(
|
||||
first: u32,
|
||||
handler: PVECTORED_EXCEPTION_HANDLER,
|
||||
) -> *mut core::ffi::c_void;
|
||||
pub fn SetThreadStackGuarantee(stacksizeinbytes: *mut u32) -> BOOL;
|
||||
}
|
||||
|
||||
pub const EXCEPTION_STACK_OVERFLOW: NTSTATUS = 0xC00000FD_u32 as _;
|
||||
pub const EXCEPTION_CONTINUE_SEARCH: i32 = 1i32;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct EXCEPTION_POINTERS {
|
||||
pub ExceptionRecord: *mut EXCEPTION_RECORD,
|
||||
// We don't need this field here
|
||||
// pub Context: *mut CONTEXT,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct EXCEPTION_RECORD {
|
||||
pub ExceptionCode: NTSTATUS,
|
||||
pub ExceptionFlags: u32,
|
||||
pub ExceptionRecord: *mut EXCEPTION_RECORD,
|
||||
pub ExceptionAddress: *mut core::ffi::c_void,
|
||||
pub NumberParameters: u32,
|
||||
pub ExceptionInformation: [usize; 15],
|
||||
}
|
||||
}
|
||||
|
||||
/// Reserve stack space for use in stack overflow exceptions.
|
||||
fn reserve_stack() {
|
||||
let result = unsafe { c::SetThreadStackGuarantee(&mut 0x5000) };
|
||||
// Reserving stack space is not critical so we allow it to fail in the released build of libstd.
|
||||
// We still use debug assert here so that CI will test that we haven't made a mistake calling the function.
|
||||
debug_assert_ne!(result, 0, "failed to reserve stack space for exception handling");
|
||||
}
|
||||
|
||||
unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> i32 {
|
||||
// SAFETY: It's up to the caller (which in this case is the OS) to ensure that `ExceptionInfo` is valid.
|
||||
unsafe {
|
||||
let rec = &(*(*ExceptionInfo).ExceptionRecord);
|
||||
let code = rec.ExceptionCode;
|
||||
|
||||
if code == c::EXCEPTION_STACK_OVERFLOW {
|
||||
crate::thread::with_current_name(|name| {
|
||||
let name = name.unwrap_or("<unknown>");
|
||||
rtprintpanic!("\nthread '{name}' has overflowed its stack\n");
|
||||
});
|
||||
}
|
||||
c::EXCEPTION_CONTINUE_SEARCH
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn init() {
|
||||
// SAFETY: `vectored_handler` has the correct ABI and is safe to call during exception handling.
|
||||
unsafe {
|
||||
let result = c::AddVectoredExceptionHandler(0, Some(vectored_handler));
|
||||
// Similar to the above, adding the stack overflow handler is allowed to fail
|
||||
// but a debug assert is used so CI will still test that it normally works.
|
||||
debug_assert!(!result.is_null(), "failed to install exception handler");
|
||||
}
|
||||
// Set the thread stack guarantee for the main thread.
|
||||
reserve_stack();
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup() {}
|
||||
|
||||
pub unsafe fn make_handler(main_thread: bool) -> super::Handler {
|
||||
if !main_thread {
|
||||
reserve_stack();
|
||||
}
|
||||
super::Handler::null()
|
||||
}
|
||||
|
||||
pub unsafe fn drop_handler(_data: *mut libc::c_void) {}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue