Skip to content

Commit 3321c2d

Browse files
committed
Auto merge of rust-lang#2626 - RalfJung:pthread_setname_np, r=RalfJung
pthread_setname_np returns an int on macOS Fixes rust-lang/miri#2625
2 parents bd4a56b + 6e3b0df commit 3321c2d

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

src/tools/miri/src/shims/unix/macos/foreign_items.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
177177
let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
178178
let thread = this.pthread_self()?;
179179
let max_len = this.eval_libc("MAXTHREADNAMESIZE")?.to_machine_usize(this)?;
180-
this.pthread_setname_np(
180+
let res = this.pthread_setname_np(
181181
thread,
182182
this.read_scalar(name)?,
183183
max_len.try_into().unwrap(),
184184
)?;
185+
// Contrary to the manpage, `pthread_setname_np` on macOS still
186+
// returns an integer indicating success.
187+
this.write_scalar(res, dest)?;
185188
}
186189
"pthread_getname_np" => {
187190
let [thread, name, len] =

src/tools/miri/tests/pass-dep/shims/pthreads.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ignore-target-windows: No libc on Windows
22
#![feature(cstr_from_bytes_until_nul)]
3-
use std::ffi::CStr;
3+
use std::ffi::{CStr, CString};
44
use std::thread;
55

66
fn main() {
@@ -135,18 +135,30 @@ fn test_named_thread_truncation() {
135135
.chain(std::iter::repeat(" yada").take(100))
136136
.collect::<String>();
137137

138+
fn set_thread_name(name: &CStr) -> i32 {
139+
#[cfg(target_os = "linux")]
140+
return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) };
141+
#[cfg(target_os = "macos")]
142+
return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) };
143+
}
144+
138145
let result = thread::Builder::new().name(long_name.clone()).spawn(move || {
139146
// Rust remembers the full thread name itself.
140147
assert_eq!(thread::current().name(), Some(long_name.as_str()));
141148

142149
// But the system is limited -- make sure we successfully set a truncation.
143150
let mut buf = vec![0u8; long_name.len() + 1];
144151
unsafe {
145-
libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len());
146-
}
152+
libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len())
153+
};
147154
let cstr = CStr::from_bytes_until_nul(&buf).unwrap();
148155
assert!(cstr.to_bytes().len() >= 15); // POSIX seems to promise at least 15 chars
149156
assert!(long_name.as_bytes().starts_with(cstr.to_bytes()));
157+
158+
// Also test directly calling pthread_setname to check its return value.
159+
assert_eq!(set_thread_name(&cstr), 0);
160+
// But with a too long name it should fail.
161+
assert_ne!(set_thread_name(&CString::new(long_name).unwrap()), 0);
150162
});
151163
result.unwrap().join().unwrap();
152164
}

0 commit comments

Comments
 (0)