Fix prctl SET_NAME and GET_NAME behaviour.
This commit is contained in:
parent
603ec0b3d8
commit
48da0cf489
3 changed files with 25 additions and 10 deletions
|
|
@ -99,11 +99,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
let option = this.read_scalar(option)?.to_i32()?;
|
||||
if option == this.eval_libc_i32("PR_SET_NAME")? {
|
||||
let address = this.read_scalar(arg2)?.not_undef()?;
|
||||
let name = this.memory.read_c_str(address)?.to_owned();
|
||||
let mut name = this.memory.read_c_str(address)?.to_owned();
|
||||
// The name should be no more than 16 bytes, including the null
|
||||
// byte. Since `read_c_str` returns the string without the null
|
||||
// byte, we need to truncate to 15.
|
||||
name.truncate(15);
|
||||
this.set_active_thread_name(name)?;
|
||||
} else if option == this.eval_libc_i32("PR_GET_NAME")? {
|
||||
let address = this.read_scalar(arg2)?.not_undef()?;
|
||||
let name = this.get_active_thread_name()?.to_vec();
|
||||
let mut name = this.get_active_thread_name()?.to_vec();
|
||||
name.push(0u8);
|
||||
assert!(name.len() <= 16);
|
||||
this.memory.write_bytes(address, name)?;
|
||||
} else {
|
||||
throw_unsup_format!("unsupported prctl option {}", option);
|
||||
|
|
|
|||
|
|
@ -313,11 +313,11 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
|
|||
}
|
||||
|
||||
/// Get the name of the active thread.
|
||||
fn get_thread_name(&self) -> InterpResult<'tcx, &[u8]> {
|
||||
fn get_thread_name(&self) -> &[u8] {
|
||||
if let Some(ref thread_name) = self.active_thread_ref().thread_name {
|
||||
Ok(thread_name)
|
||||
thread_name
|
||||
} else {
|
||||
throw_ub_format!("thread {:?} has no name set", self.active_thread)
|
||||
b"<unnamed>"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -574,7 +574,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
'mir: 'c,
|
||||
{
|
||||
let this = self.eval_context_ref();
|
||||
this.machine.threads.get_thread_name()
|
||||
Ok(this.machine.threads.get_thread_name())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -147,12 +147,21 @@ fn test_rwlock_libc_static_initializer() {
|
|||
#[cfg(target_os = "linux")]
|
||||
fn test_prctl_thread_name() {
|
||||
use std::ffi::CString;
|
||||
use libc::c_long;
|
||||
unsafe {
|
||||
let mut buf = [255; 10];
|
||||
assert_eq!(libc::prctl(libc::PR_GET_NAME, buf.as_mut_ptr() as c_long, 0 as c_long, 0 as c_long, 0 as c_long), 0);
|
||||
assert_eq!(b"<unnamed>\0", &buf);
|
||||
let thread_name = CString::new("hello").expect("CString::new failed");
|
||||
assert_eq!(libc::prctl(libc::PR_SET_NAME, thread_name.as_ptr() as libc::c_long, 0 as libc::c_long, 0 as libc::c_long, 0 as libc::c_long), 0);
|
||||
let mut buf = [0; 6];
|
||||
assert_eq!(libc::prctl(libc::PR_GET_NAME, buf.as_mut_ptr() as libc::c_long, 0 as libc::c_long, 0 as libc::c_long, 0 as libc::c_long), 0);
|
||||
assert_eq!(thread_name.as_bytes_with_nul(), buf);
|
||||
assert_eq!(libc::prctl(libc::PR_SET_NAME, thread_name.as_ptr() as c_long, 0 as c_long, 0 as c_long, 0 as c_long), 0);
|
||||
let mut buf = [255; 6];
|
||||
assert_eq!(libc::prctl(libc::PR_GET_NAME, buf.as_mut_ptr() as c_long, 0 as c_long, 0 as c_long, 0 as c_long), 0);
|
||||
assert_eq!(b"hello\0", &buf);
|
||||
let long_thread_name = CString::new("01234567890123456789").expect("CString::new failed");
|
||||
assert_eq!(libc::prctl(libc::PR_SET_NAME, long_thread_name.as_ptr() as c_long, 0 as c_long, 0 as c_long, 0 as c_long), 0);
|
||||
let mut buf = [255; 16];
|
||||
assert_eq!(libc::prctl(libc::PR_GET_NAME, buf.as_mut_ptr() as c_long, 0 as c_long, 0 as c_long, 0 as c_long), 0);
|
||||
assert_eq!(b"012345678901234\0", &buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue