Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
16 changes: 8 additions & 8 deletions compiler/rustc_error_codes/src/error_codes/E0591.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ This pattern should be rewritten. There are a few possible ways to do this:
and do the cast in the fn body (the preferred option)
- cast the fn item of a fn pointer before calling transmute, as shown here:

```
# extern "C" fn foo(_: Box<i32>) {}
# use std::mem::transmute;
# unsafe {
let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_));
let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too
# }
```
```
# extern "C" fn foo(_: Box<i32>) {}
# use std::mem::transmute;
# unsafe {
let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_));
let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too
# }
```

The same applies to transmutes to `*mut fn()`, which were observed in practice.
Note though that use of this type is generally incorrect.
Expand Down
33 changes: 17 additions & 16 deletions library/std/src/sys/pal/unix/stack_overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ pub struct Handler {
}

impl Handler {
pub unsafe fn new(thread_name: Option<Box<str>>) -> Handler {
make_handler(false, thread_name)
pub unsafe fn new() -> Handler {
make_handler(false)
}

fn null() -> Handler {
Expand Down Expand Up @@ -117,8 +117,15 @@ mod imp {
if let Some(thread_info) = thread_info
&& thread_info.guard_page_range.contains(&fault_addr)
{
let name = thread_info.thread_name.as_deref().unwrap_or("<unknown>");
let tid = crate::thread::current_os_id();
// Hey you! Yes, you modifying the stack overflow message!
// Please make sure that all functions called here are
// actually async-signal-safe. If they're not, try retrieving
// the information beforehand and storing it in `ThreadInfo`.
// Thank you!
// - says Jonas after having had to watch his carefully
// written code get made unsound again.
let tid = thread_info.tid;
let name = thread_info.name.as_deref().unwrap_or("<unknown>");
rtprintpanic!("\nthread '{name}' ({tid}) has overflowed its stack\n");
rtabort!("stack overflow");
}
Expand Down Expand Up @@ -164,12 +171,12 @@ mod imp {
if !NEED_ALTSTACK.load(Ordering::Relaxed) {
// haven't set up our sigaltstack yet
NEED_ALTSTACK.store(true, Ordering::Release);
let handler = unsafe { make_handler(true, None) };
let handler = unsafe { make_handler(true) };
MAIN_ALTSTACK.store(handler.data, Ordering::Relaxed);
mem::forget(handler);

if let Some(guard_page_range) = guard_page_range.take() {
set_current_info(guard_page_range, Some(Box::from("main")));
set_current_info(guard_page_range);
}
}

Expand Down Expand Up @@ -240,14 +247,14 @@ mod imp {
/// # Safety
/// Mutates the alternate signal stack
#[forbid(unsafe_op_in_unsafe_fn)]
pub unsafe fn make_handler(main_thread: bool, thread_name: Option<Box<str>>) -> Handler {
pub unsafe fn make_handler(main_thread: bool) -> Handler {
if cfg!(panic = "immediate-abort") || !NEED_ALTSTACK.load(Ordering::Acquire) {
return Handler::null();
}

if !main_thread {
if let Some(guard_page_range) = unsafe { current_guard() } {
set_current_info(guard_page_range, thread_name);
set_current_info(guard_page_range);
}
}

Expand Down Expand Up @@ -633,10 +640,7 @@ mod imp {

pub unsafe fn cleanup() {}

pub unsafe fn make_handler(
_main_thread: bool,
_thread_name: Option<Box<str>>,
) -> super::Handler {
pub unsafe fn make_handler(_main_thread: bool) -> super::Handler {
super::Handler::null()
}

Expand Down Expand Up @@ -720,10 +724,7 @@ mod imp {

pub unsafe fn cleanup() {}

pub unsafe fn make_handler(
main_thread: bool,
_thread_name: Option<Box<str>>,
) -> super::Handler {
pub unsafe fn make_handler(main_thread: bool) -> super::Handler {
if !main_thread {
reserve_stack();
}
Expand Down
10 changes: 7 additions & 3 deletions library/std/src/sys/pal/unix/stack_overflow/thread_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sys::os::errno_location;

pub struct ThreadInfo {
pub tid: u64,
pub name: Option<Box<str>>,
pub guard_page_range: Range<usize>,
pub thread_name: Option<Box<str>>,
}

static LOCK: Mutex<()> = Mutex::new(());
Expand Down Expand Up @@ -108,14 +109,17 @@ fn spin_lock_in_setup(this: usize) -> UnlockOnDrop {
}
}

pub fn set_current_info(guard_page_range: Range<usize>, thread_name: Option<Box<str>>) {
pub fn set_current_info(guard_page_range: Range<usize>) {
let tid = crate::thread::current_os_id();
let name = crate::thread::with_current_name(|name| name.map(Box::from));

let this = errno_location().addr();
let _lock_guard = LOCK.lock();
let _spin_guard = spin_lock_in_setup(this);

// SAFETY: we own the spin lock, so `THREAD_INFO` cannot be aliased.
let thread_info = unsafe { &mut *(&raw mut THREAD_INFO) };
thread_info.insert(this, ThreadInfo { guard_page_range, thread_name });
thread_info.insert(this, ThreadInfo { tid, name, guard_page_range });
}

pub fn delete_current_info() {
Expand Down
9 changes: 4 additions & 5 deletions library/std/src/sys/thread/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::sys::weak::dlsym;
#[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto",))]
use crate::sys::weak::weak;
use crate::sys::{os, stack_overflow};
use crate::thread::{ThreadInit, current};
use crate::thread::ThreadInit;
use crate::time::Duration;
use crate::{cmp, io, ptr};
#[cfg(not(any(
Expand Down Expand Up @@ -111,10 +111,9 @@ impl Thread {
let init = Box::from_raw(data as *mut ThreadInit);
let rust_start = init.init();

// Set up our thread name and stack overflow handler which may get triggered
// if we run out of stack.
let thread = current();
let _handler = stack_overflow::Handler::new(thread.name().map(Box::from));
// Now that the thread information is set, set up our stack
// overflow handler.
let _handler = stack_overflow::Handler::new();

rust_start();
}
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/explain/basic.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ This pattern should be rewritten. There are a few possible ways to do this:
and do the cast in the fn body (the preferred option)
- cast the fn item of a fn pointer before calling transmute, as shown here:

```
let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_));
let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too
```
```
let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_));
let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too
```

The same applies to transmutes to `*mut fn()`, which were observed in practice.
Note though that use of this type is generally incorrect.
Expand Down
Loading