diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index 9e531accd06a..25aece5989b9 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -434,7 +434,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } // Architecture-specific shims - "llvm.x86.sse2.pause" if this.tcx.sess.target.target.arch == "x86" || this.tcx.sess.target.target.arch == "x86_64" => {} + "llvm.x86.sse2.pause" if this.tcx.sess.target.target.arch == "x86" || this.tcx.sess.target.target.arch == "x86_64" => { + this.sched_yield()?; + } // Platform-specific shims _ => match this.tcx.sess.target.target.target_os.as_str() { diff --git a/src/shims/foreign_items/posix/macos.rs b/src/shims/foreign_items/posix/macos.rs index 0e3019ce33a3..3677960fd877 100644 --- a/src/shims/foreign_items/posix/macos.rs +++ b/src/shims/foreign_items/posix/macos.rs @@ -98,6 +98,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx this.write_scalar(stack_size, dest)?; } + // Threading + "pthread_setname_np" => { + let ptr = this.read_scalar(args[0])?.not_undef()?; + this.pthread_setname_np(ptr)?; + } + // Incomplete shims that we "stub out" just to get pre-main initialization code to work. // These shims are enabled only when the caller is in the standard library. "mmap" if this.frame().instance.to_string().starts_with("std::sys::unix::") => { diff --git a/src/shims/thread.rs b/src/shims/thread.rs index 2f553c1c729e..ac1bb39a6982 100644 --- a/src/shims/thread.rs +++ b/src/shims/thread.rs @@ -95,6 +95,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx _arg5: OpTy<'tcx, Tag>, ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); + this.assert_target_os("linux", "prctl"); let option = this.read_scalar(option)?.to_i32()?; if option == this.eval_libc_i32("PR_SET_NAME")? { @@ -118,6 +119,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx Ok(0) } + fn pthread_setname_np( + &mut self, + ptr: Scalar, + ) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + this.assert_target_os("macos", "pthread_setname_np"); + + let name = this.memory.read_c_str(ptr)?.to_owned(); + this.set_active_thread_name(name)?; + + Ok(()) + } + fn sched_yield(&mut self) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); diff --git a/src/thread.rs b/src/thread.rs index 376920e225ba..2119175e12cc 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -134,16 +134,20 @@ impl<'mir, 'tcx> Thread<'mir, 'tcx> { } false } + + /// Get the name of the current thread, or `` if it was not set. + fn thread_name(&self) -> &[u8] { + if let Some(ref thread_name) = self.thread_name { + thread_name + } else { + b"" + } + } } impl<'mir, 'tcx> std::fmt::Debug for Thread<'mir, 'tcx> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if let Some(ref name) = self.thread_name { - write!(f, "{}", String::from_utf8_lossy(name))?; - } else { - write!(f, "")?; - } - write!(f, "({:?}, {:?})", self.state, self.join_status) + write!(f, "{}({:?}, {:?})", String::from_utf8_lossy(self.thread_name()), self.state, self.join_status) } } @@ -314,11 +318,7 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> { /// Get the name of the active thread. fn get_thread_name(&self) -> &[u8] { - if let Some(ref thread_name) = self.active_thread_ref().thread_name { - thread_name - } else { - b"" - } + self.active_thread_ref().thread_name() } /// Allocate a new blockset id. diff --git a/tests/run-pass/concurrency/simple.rs b/tests/run-pass/concurrency/simple.rs index ad47bb144b58..c22506821f54 100644 --- a/tests/run-pass/concurrency/simple.rs +++ b/tests/run-pass/concurrency/simple.rs @@ -49,6 +49,25 @@ fn create_move_out() { assert_eq!(result.len(), 6); } +fn panic() { + let result = thread::spawn(|| { + panic!("Hello!") + }) + .join() + .unwrap_err(); + let msg = result.downcast_ref::<&'static str>().unwrap(); + assert_eq!(*msg, "Hello!"); +} + +fn panic_named() { + thread::Builder::new().name("childthread".to_string()).spawn(move || { + panic!("Hello, world!"); + }) + .unwrap() + .join() + .unwrap_err(); +} + fn main() { create_and_detach(); create_and_join(); @@ -58,4 +77,6 @@ fn main() { create_nested_and_join(); create_move_in(); create_move_out(); + panic(); + panic_named(); } diff --git a/tests/run-pass/concurrency/simple.stderr b/tests/run-pass/concurrency/simple.stderr index 2dbfb7721d36..e52d07cdc73f 100644 --- a/tests/run-pass/concurrency/simple.stderr +++ b/tests/run-pass/concurrency/simple.stderr @@ -1,2 +1,4 @@ warning: thread support is experimental. For example, Miri does not detect data races yet. +thread '' panicked at 'Hello!', $DIR/simple.rs:54:9 +thread 'childthread' panicked at 'Hello, world!', $DIR/simple.rs:64:9 diff --git a/tests/run-pass/sync.rs b/tests/run-pass/sync.rs index a4fd6f584c58..8b8594d4df69 100644 --- a/tests/run-pass/sync.rs +++ b/tests/run-pass/sync.rs @@ -1,7 +1,8 @@ -#![feature(rustc_private)] +#![feature(rustc_private, renamed_spin_loop)] use std::sync::{Mutex, TryLockError}; use std::sync::atomic; +use std::hint; fn main() { test_mutex_stdlib(); @@ -56,6 +57,7 @@ impl TryLockErrorExt for TryLockError { fn test_spin_loop_hint() { atomic::spin_loop_hint(); + hint::spin_loop(); } fn test_thread_yield_now() { diff --git a/tests/run-pass/transmute_fat2.rs b/tests/run-pass/transmute_fat2.rs index 8cbe9a099bb6..c667aab6bb5f 100644 --- a/tests/run-pass/transmute_fat2.rs +++ b/tests/run-pass/transmute_fat2.rs @@ -8,5 +8,6 @@ fn main() { let bad = unsafe { std::mem::transmute::(42) }; + // This created a slice with length 0, so the following will fail the bounds check. bad[0]; } diff --git a/tests/run-pass/transmute_fat2.stderr b/tests/run-pass/transmute_fat2.stderr index 08849a5b517a..2539e58814d6 100644 --- a/tests/run-pass/transmute_fat2.stderr +++ b/tests/run-pass/transmute_fat2.stderr @@ -1 +1 @@ -thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', $DIR/transmute_fat2.rs:11:5 +thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', $DIR/transmute_fat2.rs:12:5