freebsd interceptions update proposal

This commit is contained in:
David Carlier 2023-10-26 20:38:32 +01:00
parent fe0b970992
commit be6f27b686
3 changed files with 45 additions and 7 deletions

View File

@ -108,7 +108,7 @@ case $HOST_TARGET in
MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic env/var MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthreads atomic env/var
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm

View File

@ -29,13 +29,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
"pthread_set_name_np" => { "pthread_set_name_np" => {
let [thread, name] = let [thread, name] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let max_len = usize::MAX; // freebsd does not seem to have a limit. let max_len = usize::MAX; // FreeBSD does not seem to have a limit.
let res = this.pthread_setname_np( // FreeBSD's pthread_set_name_np does not return anything.
this.pthread_setname_np(
this.read_scalar(thread)?, this.read_scalar(thread)?,
this.read_scalar(name)?, this.read_scalar(name)?,
max_len, max_len,
)?; )?;
this.write_scalar(res, dest)?; }
"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.
this.pthread_getname_np(
this.read_scalar(thread)?,
this.read_scalar(name)?,
this.read_scalar(len)?,
)?;
} }
// errno // errno

View File

@ -1,18 +1,26 @@
//@ignore-target-windows: No libc on Windows //@ignore-target-windows: No libc on Windows
use std::ffi::{CStr, CString}; use std::ffi::CStr;
#[cfg(not(target_os = "freebsd"))]
use std::ffi::CString;
use std::thread; use std::thread;
fn main() { fn main() {
#[cfg(not(target_os = "freebsd"))]
test_mutex_libc_init_recursive(); test_mutex_libc_init_recursive();
#[cfg(not(target_os = "freebsd"))]
test_mutex_libc_init_normal(); test_mutex_libc_init_normal();
#[cfg(not(target_os = "freebsd"))]
test_mutex_libc_init_errorcheck(); test_mutex_libc_init_errorcheck();
#[cfg(not(target_os = "freebsd"))]
test_rwlock_libc_static_initializer(); test_rwlock_libc_static_initializer();
test_named_thread_truncation(); test_named_thread_truncation();
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
test_mutex_libc_static_initializer_recursive(); test_mutex_libc_static_initializer_recursive();
} }
#[cfg(not(target_os = "freebsd"))]
fn test_mutex_libc_init_recursive() { fn test_mutex_libc_init_recursive() {
unsafe { unsafe {
let mut attr: libc::pthread_mutexattr_t = std::mem::zeroed(); let mut attr: libc::pthread_mutexattr_t = std::mem::zeroed();
@ -37,6 +45,7 @@ fn test_mutex_libc_init_recursive() {
} }
} }
#[cfg(not(target_os = "freebsd"))]
fn test_mutex_libc_init_normal() { fn test_mutex_libc_init_normal() {
unsafe { unsafe {
let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
@ -59,6 +68,7 @@ fn test_mutex_libc_init_normal() {
} }
} }
#[cfg(not(target_os = "freebsd"))]
fn test_mutex_libc_init_errorcheck() { fn test_mutex_libc_init_errorcheck() {
unsafe { unsafe {
let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
@ -104,6 +114,7 @@ fn test_mutex_libc_static_initializer_recursive() {
// Testing the behavior of std::sync::RwLock does not fully exercise the pthread rwlock shims, we // Testing the behavior of std::sync::RwLock does not fully exercise the pthread rwlock shims, we
// need to go a layer deeper and test the behavior of the libc functions, because // need to go a layer deeper and test the behavior of the libc functions, because
// std::sys::unix::rwlock::RWLock itself keeps track of write_locked and num_readers. // std::sys::unix::rwlock::RWLock itself keeps track of write_locked and num_readers.
#[cfg(not(target_os = "freebsd"))]
fn test_rwlock_libc_static_initializer() { fn test_rwlock_libc_static_initializer() {
let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
unsafe { unsafe {
@ -137,6 +148,14 @@ fn test_named_thread_truncation() {
fn set_thread_name(name: &CStr) -> i32 { fn set_thread_name(name: &CStr) -> i32 {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) }; return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) };
#[cfg(target_os = "freebsd")]
unsafe {
// pthread_set_name_np does not return anything only it can fail if the
// thread id is invalid
libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr().cast())
};
#[cfg(target_os = "freebsd")]
return 0;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) }; return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) };
} }
@ -147,16 +166,25 @@ fn test_named_thread_truncation() {
// But the system is limited -- make sure we successfully set a truncation. // But the system is limited -- make sure we successfully set a truncation.
let mut buf = vec![0u8; long_name.len() + 1]; let mut buf = vec![0u8; long_name.len() + 1];
#[cfg(not(target_os = "freebsd"))]
unsafe { 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())
}; };
#[cfg(target_os = "freebsd")]
unsafe {
// pthread_get_name_np does not return anything only it can fail if the
// thread id is invalid
libc::pthread_get_name_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len())
};
let cstr = CStr::from_bytes_until_nul(&buf).unwrap(); let cstr = CStr::from_bytes_until_nul(&buf).unwrap();
assert!(cstr.to_bytes().len() >= 15); // POSIX seems to promise at least 15 chars assert!(cstr.to_bytes().len() >= 15, "name is too short: len={}", cstr.to_bytes().len()); // POSIX seems to promise at least 15 chars
assert!(long_name.as_bytes().starts_with(cstr.to_bytes())); assert!(long_name.as_bytes().starts_with(cstr.to_bytes()));
// Also test directly calling pthread_setname to check its return value. // Also test directly calling pthread_setname to check its return value.
assert_eq!(set_thread_name(&cstr), 0); assert_eq!(set_thread_name(&cstr), 0);
// But with a too long name it should fail. // But with a too long name it should fail (except on FreeBSD where the
// function has no return, hence cannot indicate failure).
#[cfg(not(target_os = "freebsd"))]
assert_ne!(set_thread_name(&CString::new(long_name).unwrap()), 0); assert_ne!(set_thread_name(&CString::new(long_name).unwrap()), 0);
}); });
result.unwrap().join().unwrap(); result.unwrap().join().unwrap();