From 79060003513627a258e9512330f052adcda8f2e6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Oct 2022 10:31:43 +0200 Subject: [PATCH] pthread_setname_np returns an int on macOS --- src/shims/unix/macos/foreign_items.rs | 5 ++++- tests/pass-dep/shims/pthreads.rs | 18 +++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/shims/unix/macos/foreign_items.rs b/src/shims/unix/macos/foreign_items.rs index 371f56ca35..221dc39697 100644 --- a/src/shims/unix/macos/foreign_items.rs +++ b/src/shims/unix/macos/foreign_items.rs @@ -177,11 +177,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let thread = this.pthread_self()?; let max_len = this.eval_libc("MAXTHREADNAMESIZE")?.to_machine_usize(this)?; - this.pthread_setname_np( + let res = this.pthread_setname_np( thread, this.read_scalar(name)?, max_len.try_into().unwrap(), )?; + // Contrary to the manpage, `pthread_setname_np` on macOS still + // returns an integer indicating success. + this.write_scalar(res, dest)?; } "pthread_getname_np" => { let [thread, name, len] = diff --git a/tests/pass-dep/shims/pthreads.rs b/tests/pass-dep/shims/pthreads.rs index bbddca7475..ae02a8e3c9 100644 --- a/tests/pass-dep/shims/pthreads.rs +++ b/tests/pass-dep/shims/pthreads.rs @@ -1,6 +1,6 @@ //@ignore-target-windows: No libc on Windows #![feature(cstr_from_bytes_until_nul)] -use std::ffi::CStr; +use std::ffi::{CStr, CString}; use std::thread; fn main() { @@ -135,6 +135,13 @@ fn test_named_thread_truncation() { .chain(std::iter::repeat(" yada").take(100)) .collect::(); + fn set_thread_name(name: &CStr) -> i32 { + #[cfg(target_os = "linux")] + return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) }; + #[cfg(target_os = "macos")] + return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) }; + } + let result = thread::Builder::new().name(long_name.clone()).spawn(move || { // Rust remembers the full thread name itself. assert_eq!(thread::current().name(), Some(long_name.as_str())); @@ -142,11 +149,16 @@ fn test_named_thread_truncation() { // But the system is limited -- make sure we successfully set a truncation. let mut buf = vec![0u8; long_name.len() + 1]; unsafe { - libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len()); - } + libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len()) + }; let cstr = CStr::from_bytes_until_nul(&buf).unwrap(); assert!(cstr.to_bytes().len() >= 15); // POSIX seems to promise at least 15 chars assert!(long_name.as_bytes().starts_with(cstr.to_bytes())); + + // 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. + assert_ne!(set_thread_name(&CString::new(long_name).unwrap()), 0); }); result.unwrap().join().unwrap(); }