Skip to content

Commit

Permalink
Fixed get thread name behavior for FreeBSD
Browse files Browse the repository at this point in the history
  • Loading branch information
YohDeadfall committed Oct 12, 2024
1 parent 0c93071 commit 00ae882
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 8 deletions.
7 changes: 5 additions & 2 deletions src/shims/unix/freebsd/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"pthread_get_name_np" => {
let [thread, name, len] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
// FreeBSD's pthread_get_name_np does not return anything.
// FreeBSD's pthread_get_name_np does not return anything
// and uses strlcpy, which truncates the resulting value,
// but always adds a null terminator (except for zero-sized buffers).
// https://github.com/freebsd/freebsd-src/blob/c2d93a803acef634bd0eede6673aeea59e90c277/lib/libthr/thread/thr_info.c#L119-L144
this.pthread_getname_np(
this.read_scalar(thread)?,
this.read_scalar(name)?,
this.read_scalar(len)?,
false,
/* truncate */ true,
)?;
}

Expand Down
11 changes: 5 additions & 6 deletions tests/pass-dep/libc/pthread-threadname.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,9 @@ fn main() {
// if the buffer is shorter than the thread name.
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
assert_eq!(get_thread_name(&mut buf[..4]), libc::ERANGE);

// For libc implementation for macOS it's not an error
// for a buffer being too short for the thread name.
#[cfg(target_os = "macos")]
// On macOS and FreeBSD it's not an error for the buffer to be
// too short for the thread name -- they truncate instead.
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
{
// Ensure that a zero sized buffer returns no error.
assert_eq!(get_thread_name(&mut buf[..0]), 0);
Expand Down Expand Up @@ -123,8 +122,8 @@ fn main() {
// Also test directly calling pthread_setname to check its return value.
assert_eq!(set_thread_name(&cstr), 0);

// But with a too long name it should fail (except on FreeBSD where the
// function has no return, hence cannot indicate failure).
// But with a too long name it should fail (except on FreeBSD where
// names of arbitrary size seem to be supported).
// On macOS, the error code is different.
#[cfg(not(any(target_os = "freebsd", target_os = "macos")))]
assert_eq!(set_thread_name(&CString::new(long_name).unwrap()), libc::ERANGE);
Expand Down

0 comments on commit 00ae882

Please sign in to comment.