Closed zjp-CN closed 3 weeks ago
I think the bug is that we're using a u64
of nanoseconds inside the virtual clock which is not capable of handling this totally legitimate futex call:
futex(0x55e3a92ffa4c, FUTEX_WAIT_BITSET_PRIVATE, 2, {tv_sec=18446744083902, tv_nsec=117558982}, FUTEX_BITSET_MATCH_ANY)
We're using u64
because Duration::from_nanos
requires it but the function's documentation has a big warning https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_nanos:
Note: Using this on the return value of as_nanos() might cause unexpected behavior: as_nanos() returns a u128, and can return values that do not fit in u64, e.g. 585 years. Instead, consider using the pattern Duration::new(d.as_secs(), d.subsec_nanos()) if you cannot copy/clone the Duration directly.
We should be using Duration::new
instead of Duration::from_nanos
, then we should at least convert the virtual clock to a u128
of nanoseconds. Possibly we should match its internals to what is in the standard library types.
The changes are all in this file and look rather approachable to me: https://github.com/rust-lang/miri/blob/38e318ccd255a090eb57e19d2aac5ed2ec0e2b92/src/clock.rs
Yeah I guess that should either be u128 (and argue carefully why that cannot overflow) or use saturating arithmetic - waking up early is always fine.
The code works fine with
cargo run
, butcargo miri run
will always emit ice