From e9aa2517353bf44c42843aeb69d88a0005128afc Mon Sep 17 00:00:00 2001 From: Runji Wang Date: Sun, 7 Apr 2024 17:23:28 +0900 Subject: [PATCH] fix(madsim): fix determinism for getrandom (#202) * fix determinism for getrandom Signed-off-by: Runji Wang * bump version Signed-off-by: Runji Wang * fix in another way Signed-off-by: Runji Wang --------- Signed-off-by: Runji Wang --- CHANGELOG.md | 6 ++++++ Cargo.toml | 3 +++ madsim/Cargo.toml | 3 ++- madsim/src/sim/rand.rs | 35 ++++++++++++++++++++++++++++++++--- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8afd720..2e48f56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## madsim [0.2.27] - 2024-04-07 + +### Fixed + +- Fix the problem that `getrandom` returns different values in multiple runs with the same seed. + ## rdkafka [0.3.4] - 2024-03-22 ### Fixed diff --git a/Cargo.toml b/Cargo.toml index fc1ad72..f5620d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,6 @@ members = [ "tonic-example", ] resolver = "2" + +[patch.crates-io] +getrandom = { git = "https://github.com/madsim-rs/getrandom.git", rev = "6c9d9e9" } diff --git a/madsim/Cargo.toml b/madsim/Cargo.toml index 0037dee..d641508 100644 --- a/madsim/Cargo.toml +++ b/madsim/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "madsim" -version = "0.2.26" +version = "0.2.27" edition = "2021" authors = ["Runji Wang "] description = "Deterministic Simulator for distributed systems." @@ -63,6 +63,7 @@ tokio-util = { version = "0.7", features = ["codec"] } criterion = "0.5" structopt = "0.3" tokio = { version = "1", features = ["rt-multi-thread", "macros", "io-util"] } +getrandom = "=0.2.13" [[bench]] name = "rpc" diff --git a/madsim/src/sim/rand.rs b/madsim/src/sim/rand.rs index cfb3063..11b7639 100644 --- a/madsim/src/sim/rand.rs +++ b/madsim/src/sim/rand.rs @@ -208,8 +208,11 @@ unsafe extern "C" fn getrandom(mut buf: *mut u8, mut buflen: usize, _flags: u32) buf = buf.add(std::mem::size_of::()); buflen -= std::mem::size_of::(); } - let val = rand.with(|rng| rng.gen::().to_ne_bytes()); - core::ptr::copy(val.as_ptr(), buf, buflen); + // note: do not modify state if buflen == 0 + if buflen != 0 { + let val = rand.with(|rng| rng.gen::().to_ne_bytes()); + core::ptr::copy(val.as_ptr(), buf, buflen); + } return len as _; } #[cfg(target_os = "linux")] @@ -265,7 +268,7 @@ unsafe extern "C" fn getentropy(buf: *mut u8, buflen: usize) -> i32 { #[cfg(test)] mod tests { use crate::runtime::Runtime; - use std::collections::{BTreeSet, HashMap}; + use std::collections::{BTreeSet, HashMap, HashSet}; #[test] #[cfg_attr(target_os = "linux", ignore)] @@ -305,4 +308,30 @@ mod tests { } assert_eq!(seqs.len(), 3, "hashmap is not deterministic"); } + + // https://github.com/madsim-rs/madsim/issues/201 + #[test] + fn getrandom_should_be_deterministic() { + let rnd_fn = || async { + let mut dst = [0]; + getrandom::getrandom(&mut dst).unwrap(); + dst + }; + let builder = crate::runtime::Builder::from_env(); + let seed = builder.seed; + let set = (0..10) + .map(|_| { + crate::runtime::Builder { + seed, + count: 1, + jobs: 1, + config: crate::Config::default(), + time_limit: None, + check: false, + } + .run(rnd_fn) + }) + .collect::>(); + assert_eq!(set.len(), 1); + } }