diff options
| author | bors <bors@rust-lang.org> | 2024-07-24 10:17:55 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-07-24 10:17:55 +0000 |
| commit | 12cb742e8258d32afefe304a8c2402a56d4a05ee (patch) | |
| tree | 3b682c3656192d814d8aca44da9b7c7e8b97c1e6 | |
| parent | 0b22f0c13d3151622200c62726600f1a805ac37e (diff) | |
| parent | a0088d7a813a1f63e5af4d6edc5d2c50a0b3702e (diff) | |
| download | rust-12cb742e8258d32afefe304a8c2402a56d4a05ee.tar.gz rust-12cb742e8258d32afefe304a8c2402a56d4a05ee.zip | |
Auto merge of #3756 - Mandragorian:gettid_support, r=RalfJung
Add `gettid` support Add support for `gettid` in miri. To ensure that the requirement that `getpid() == gettdi()` for the main thread, we use the value returned by `getpid` and add to it the internal thread index. Since `getpid` is only supported when isolation is disabled, and we want `gettid` to be used both in isolated and non-isolated executions, we modify `getpid` to return a hardcoded value (1000) when running in isolation mode. Fixes #3730
| -rw-r--r-- | src/tools/miri/src/shims/env.rs | 5 | ||||
| -rw-r--r-- | src/tools/miri/src/shims/unix/env.rs | 17 | ||||
| -rw-r--r-- | src/tools/miri/src/shims/unix/linux/foreign_items.rs | 5 | ||||
| -rw-r--r-- | src/tools/miri/src/shims/windows/env.rs | 3 | ||||
| -rw-r--r-- | src/tools/miri/tests/pass-dep/libc/gettid.rs | 22 | ||||
| -rw-r--r-- | src/tools/miri/tests/pass/getpid.rs | 15 |
6 files changed, 60 insertions, 7 deletions
diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index 7ad395cccb7..6586ea8e48c 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -108,4 +108,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { EnvVars::Windows(vars) => vars.get(name), } } + + fn get_pid(&self) -> u32 { + let this = self.eval_context_ref(); + if this.machine.communicate() { std::process::id() } else { 1000 } + } } diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index 405431f4327..3b8ad65195b 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -274,12 +274,23 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); this.assert_target_os_is_unix("getpid"); - this.check_no_isolation("`getpid`")?; - // The reason we need to do this wacky of a conversion is because // `libc::getpid` returns an i32, however, `std::process::id()` return an u32. // So we un-do the conversion that stdlib does and turn it back into an i32. #[allow(clippy::cast_possible_wrap)] - Ok(std::process::id() as i32) + Ok(this.get_pid() as i32) + } + + fn linux_gettid(&mut self) -> InterpResult<'tcx, i32> { + let this = self.eval_context_ref(); + this.assert_target_os("linux", "gettid"); + + let index = this.machine.threads.active_thread().to_u32(); + + // Compute a TID for this thread, ensuring that the main thread has PID == TID. + let tid = this.get_pid().strict_add(index); + + #[allow(clippy::cast_possible_wrap)] + Ok(tid as i32) } } diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 95bee38cd78..20c6a234794 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -94,6 +94,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; this.write_scalar(res, dest)?; } + "gettid" => { + let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let result = this.linux_gettid()?; + this.write_scalar(Scalar::from_i32(result), dest)?; + } // Dynamically invoked syscalls "syscall" => { diff --git a/src/tools/miri/src/shims/windows/env.rs b/src/tools/miri/src/shims/windows/env.rs index ed3eb697986..77ae06bd5c2 100644 --- a/src/tools/miri/src/shims/windows/env.rs +++ b/src/tools/miri/src/shims/windows/env.rs @@ -200,9 +200,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn GetCurrentProcessId(&mut self) -> InterpResult<'tcx, u32> { let this = self.eval_context_mut(); this.assert_target_os("windows", "GetCurrentProcessId"); - this.check_no_isolation("`GetCurrentProcessId`")?; - Ok(std::process::id()) + Ok(this.get_pid()) } #[allow(non_snake_case)] diff --git a/src/tools/miri/tests/pass-dep/libc/gettid.rs b/src/tools/miri/tests/pass-dep/libc/gettid.rs new file mode 100644 index 00000000000..87405b02ac3 --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/gettid.rs @@ -0,0 +1,22 @@ +//@only-target-linux +//@revisions: with_isolation without_isolation +//@[without_isolation] compile-flags: -Zmiri-disable-isolation + +use libc::{getpid, gettid}; +use std::thread; + +fn main() { + thread::spawn(|| { + // Test that in isolation mode a deterministic value will be returned. + // The value 1001 is not important, we only care that whatever the value + // is, won't change from execution to execution. + #[cfg(with_isolation)] + assert_eq!(unsafe { gettid() }, 1001); + + assert_ne!(unsafe { gettid() }, unsafe { getpid() }); + }); + + // Test that the thread ID of the main thread is the same as the process + // ID. + assert_eq!(unsafe { gettid() }, unsafe { getpid() }); +} diff --git a/src/tools/miri/tests/pass/getpid.rs b/src/tools/miri/tests/pass/getpid.rs index 733545462eb..f350fafff4a 100644 --- a/src/tools/miri/tests/pass/getpid.rs +++ b/src/tools/miri/tests/pass/getpid.rs @@ -1,9 +1,20 @@ -//@compile-flags: -Zmiri-disable-isolation +//@revisions: with_isolation without_isolation +//@[without_isolation] compile-flags: -Zmiri-disable-isolation fn getpid() -> u32 { std::process::id() } fn main() { - getpid(); + let pid = getpid(); + + std::thread::spawn(move || { + assert_eq!(getpid(), pid); + }); + + // Test that in isolation mode a deterministic value will be returned. + // The value 1000 is not important, we only care that whatever the value + // is, won't change from execution to execution. + #[cfg(with_isolation)] + assert_eq!(pid, 1000); } |
