Skip to content

Commit 9fb3bbb

Browse files
committed
various minor adjustments
1 parent 8c9d50a commit 9fb3bbb

File tree

7 files changed

+49
-79
lines changed

7 files changed

+49
-79
lines changed

doc/genmc.md

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
# **(WIP)** Documentation for Miri-GenMC
2+
23
[GenMC](https://github.com/MPI-SWS/genmc) is a stateless model checker for exploring concurrent executions of a program.
4+
Miri-GenMC integrates that model checker into Miri.
35

46
**NOTE: Currently, no actual GenMC functionality is part of Miri, this is still WIP.**
57

68
<!-- FIXME(genmc): add explanation. -->
79

810
## Usage
911

10-
**IMPORTANT: The license of GenMC and thus the `genmc-sys` crate in the Miri repo is currently "GPL-3.0-or-later", which is NOT compatible with Miri's "MIT OR Apache" license.**
11-
12-
**IMPORTANT: There should be no distribution of Miri-GenMC until all licensing questions are clarified (the `genmc` feature of Miri is OFF-BY-DEFAULT and should be OFF for all Miri releases).**
12+
**IMPORTANT: The license of GenMC and thus the `genmc-sys` crate in the Miri repo is currently "GPL-3.0-or-later", so a binary produced with the `genmc` feature is subject to the requirements of the GPL. As long as that remains the case, the `genmc` feature of Miri is OFF-BY-DEFAULT and must be OFF for all Miri releases.**
1313

1414
For testing/developing Miri-GenMC (while keeping in mind the licensing issues):
1515
- clone the Miri repo.
@@ -35,44 +35,28 @@ Some or all of these limitations might get removed in the future:
3535

3636
- Borrow tracking is currently incompatible (stacked/tree borrows).
3737
- Only Linux is supported for now.
38-
- No 32-bit platform support.
39-
- No cross-platform interpretation.
38+
- No support for 32-bit or big-endian targets.
39+
- No cross-target interpretation.
4040

4141
<!-- FIXME(genmc): document remaining limitations -->
4242

4343
## Development
4444

4545
GenMC is written in C++, which complicates development a bit.
46-
For Rust-C++ interop, Miri uses [CXX.rs](https://cxx.rs/), and all handling of C++ code is contained in the `genmc-sys` crate (located in the Miri repository root directory: `miri/genmc-sys/`).
47-
48-
Building GenMC requires a compiler with C++23 support.
49-
<!-- FIXME(genmc,llvm): remove once LLVM dependency is no longer required. -->
50-
Currently, building GenMC also requires linking to LLVM, which needs to be installed manually.
51-
52-
The actual code for GenMC is not contained in the Miri repo itself, but in a [separate GenMC repo](https://github.com/MPI-SWS/genmc) (with different maintainers).
53-
Note that this repo is just a mirror repo.
54-
<!-- FIXME(genmc): define how submitting code to GenMC should be handled. -->
46+
The prerequisites for building Miri-GenMC are:
47+
- A compiler with C++23 support.
48+
- LLVM developments headers and clang.
49+
<!-- FIXME(genmc,llvm): remove once LLVM dependency is no longer required. -->
50+
51+
The actual code for GenMC is not contained in the Miri repo itself, but in a [separate GenMC repo](https://github.com/MPI-SWS/genmc) (with its own maintainers).
52+
These sources need to be available to build Miri-GenMC.
53+
The process for obtaining them is as follows:
54+
- By default, a fixed commit of GenMC is downloaded to `genmc-sys/genmc-src` and built automatically.
55+
(The commit is determined by `GENMC_COMMIT` in `genmc-sys/build.rs`.)
56+
- If you want to overwrite that, set the `GENMC_SRC_PATH` environment variable to a path that contains the GenMC sources.
57+
If you place this directory inside the Miri folder, it is recommended to call it `genmc-src` as that tells `./miri fmt` to avoid
58+
formatting the Rust files inside that folder.
59+
60+
<!-- FIXME(genmc): explain how submitting code to GenMC should be handled. -->
5561

5662
<!-- FIXME(genmc): explain development. -->
57-
58-
### Building the GenMC Library
59-
The build script in the `genmc-sys` crate handles locating, downloading, building and linking the GenMC library.
60-
61-
To determine which GenMC repo path will be used, the following steps are taken:
62-
- If the env var `GENMC_SRC_PATH` is set, it's value is used as a path to a directory with a GenMC repo (e.g., `GENMC_SRC_PATH="path/to/miri/genmc-sys/genmc-sys-local"`).
63-
- Note that this variable must be set wherever Miri is built, e.g., in the terminal, or in the Rust Analyzer settings.
64-
- If the path `genmc-sys/genmc-src/genmc` exists, try to set the GenMC repo there to the commit we need.
65-
- If the downloaded repo doesn't exist or is missing the commit, the build script will fetch the commit over the network.
66-
- Note that the build script will *not* access the network if any of the steps previous steps succeeds.
67-
68-
Once we get the path to the repo, the compilation proceeds in two steps:
69-
- Compile GenMC into a library (using cmake).
70-
- Compile the cxx.rs bridge to connect the library to the Rust code.
71-
The first step is where all build settings are made, the relevant ones are then stored in a `config.h` file that can be included in the second compilation step.
72-
73-
#### Code Formatting
74-
Note that all directories with names starting with `genmc-src` are ignored by `./miri fmt` on purpose.
75-
GenMC also contains Rust files, but they should not be formatted with Miri's formatting rules.
76-
For working on Miri-GenMC locally, placing the GenMC repo into such a path (e.g., `miri/genmc-sys/genmc-src-local`) ensures that it is also exempt from formatting.
77-
78-
<!-- FIXME(genmc): Decide on formatting rules for Miri-GenMC interface C++ code. -->

genmc-sys/build.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::str::FromStr;
66

77
/// Path where the downloaded GenMC repository will be stored (relative to the `genmc-sys` directory).
88
/// Note that this directory is *not* cleaned up automatically by `cargo clean`.
9-
const GENMC_DOWNLOAD_PATH: &str = "./genmc-src/genmc/";
9+
const GENMC_DOWNLOAD_PATH: &str = "./genmc-src/";
1010

1111
/// Name of the library of the GenMC model checker.
1212
const GENMC_MODEL_CHECKER: &str = "genmc_lib";
@@ -122,11 +122,9 @@ mod downloading {
122122
return;
123123
}
124124

125-
println!(
126-
"HINT: For local development, set the environment variable 'GENMC_SRC_PATH' to the path of a GenMC repository.",
127-
);
128125
panic!(
129-
"Downloaded GenMC repository at path '{GENMC_DOWNLOAD_PATH}' has been modified. Please undo any changes made, or delete the '{GENMC_DOWNLOAD_PATH}' directory to have it downloaded again."
126+
"Downloaded GenMC repository at path '{GENMC_DOWNLOAD_PATH}' has been modified. Please undo any changes made, or delete the '{GENMC_DOWNLOAD_PATH}' directory to have it downloaded again.\n\
127+
HINT: For local development, set the environment variable 'GENMC_SRC_PATH' to the path of a GenMC repository."
130128
);
131129
}
132130
}
@@ -194,7 +192,7 @@ fn compile_cpp_dependencies(genmc_path: &Path) {
194192
// The actual compilation happens here:
195193
let genmc_install_dir = config.build();
196194

197-
// Add the model checker library to be linked and tell GenMC where to find it:
195+
// Add the model checker library to be linked and tell rustc where to find it:
198196
let cmake_lib_dir = genmc_install_dir.join("lib").join("genmc");
199197
println!("cargo::rustc-link-search=native={}", cmake_lib_dir.display());
200198
println!("cargo::rustc-link-lib=static={GENMC_MODEL_CHECKER}");
@@ -260,9 +258,10 @@ fn main() {
260258
compile_cpp_dependencies(&genmc_path);
261259

262260
// Only rebuild if anything changes:
263-
// Note that we don't add the downloaded GenMC repo, since that should never be modified manually.
264-
// Adding that path here would also trigger an unnecessary rebuild after the repo is cloned (since cargo detects that as a file modification).
261+
// Note that we don't add the downloaded GenMC repo, since that should never be modified
262+
// manually. Adding that path here would also trigger an unnecessary rebuild after the repo is
263+
// cloned (since cargo detects that as a file modification).
265264
println!("cargo::rerun-if-changed={RUST_CXX_BRIDGE_FILE_PATH}");
265+
println!("cargo::rerun-if-changed=./src");
266266
println!("cargo::rerun-if-changed=./src_cpp");
267-
println!("cargo::rerun-if-env-changed=GENMC_SRC_PATH");
268267
}

src/bin/miri.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,9 @@ fn main() {
596596
} else if arg == "-Zmiri-many-seeds-keep-going" {
597597
many_seeds_keep_going = true;
598598
} else if let Some(trimmed_arg) = arg.strip_prefix("-Zmiri-genmc") {
599-
GenmcConfig::parse_arg(&mut miri_config.genmc_config, trimmed_arg);
599+
if let Err(msg) = GenmcConfig::parse_arg(&mut miri_config.genmc_config, trimmed_arg) {
600+
fatal_error!("{msg}");
601+
}
600602
} else if let Some(param) = arg.strip_prefix("-Zmiri-env-forward=") {
601603
miri_config.forwarded_env_vars.push(param.to_owned());
602604
} else if let Some(param) = arg.strip_prefix("-Zmiri-env-set=") {
@@ -732,18 +734,15 @@ fn main() {
732734

733735
// Validate settings for data race detection and GenMC mode.
734736
if miri_config.genmc_config.is_some() {
735-
// FIXME(genmc): Add checks for currently supported platforms (64bit, target == host)
736737
if !miri_config.data_race_detector {
737738
fatal_error!("Cannot disable data race detection in GenMC mode (currently)");
738739
} else if !miri_config.weak_memory_emulation {
739740
fatal_error!("Cannot disable weak memory emulation in GenMC mode");
740741
}
741-
// FIXME(genmc): Remove once GenMC mode is compatible with borrow tracking:
742742
if miri_config.borrow_tracker.is_some() {
743743
eprintln!(
744-
"warning: Borrow tracking has been disabled, it is not (yet) supported in GenMC mode."
744+
"warning: borrow tracking has been disabled, it is not (yet) supported in GenMC mode."
745745
);
746-
eprintln!();
747746
miri_config.borrow_tracker = None;
748747
}
749748
} else if miri_config.weak_memory_emulation && !miri_config.data_race_detector {

src/concurrency/genmc/config.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,17 @@ impl GenmcConfig {
1717
/// Passing any GenMC argument will enable GenMC mode.
1818
///
1919
/// `trimmed_arg` should be the argument to be parsed, with the suffix "-Zmiri-genmc" removed.
20-
pub fn parse_arg(genmc_config: &mut Option<GenmcConfig>, trimmed_arg: &str) {
21-
// FIXME(genmc,macos): Add `target_os = "macos"` once `https://github.com/dtolnay/cxx/issues/1535` is fixed.
22-
if !cfg!(all(
23-
feature = "genmc",
24-
any(target_os = "linux", target_os = "macos"),
25-
target_pointer_width = "64",
26-
target_endian = "little"
27-
)) {
28-
unimplemented!(
29-
"GenMC mode is not supported on this platform, cannot handle argument: \"-Zmiri-genmc{trimmed_arg}\""
30-
);
31-
}
20+
pub fn parse_arg(
21+
genmc_config: &mut Option<GenmcConfig>,
22+
trimmed_arg: &str,
23+
) -> Result<(), String> {
24+
// FIXME(genmc): Ensure host == target somewhere.
25+
3226
if genmc_config.is_none() {
3327
*genmc_config = Some(Default::default());
3428
}
3529
if trimmed_arg.is_empty() {
36-
return; // this corresponds to "-Zmiri-genmc"
30+
return Ok(()); // this corresponds to "-Zmiri-genmc"
3731
}
3832
// FIXME(GenMC): implement remaining parameters.
3933
todo!();

src/concurrency/genmc/dummy.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -227,21 +227,14 @@ impl VisitProvenance for GenmcCtx {
227227
}
228228

229229
impl GenmcConfig {
230-
pub fn parse_arg(_genmc_config: &mut Option<GenmcConfig>, trimmed_arg: &str) {
231-
// FIXME(genmc,macos): Add `target_os = "macos"` once `https://github.com/dtolnay/cxx/issues/1535` is fixed.
232-
if cfg!(all(
233-
feature = "genmc",
234-
any(target_os = "linux", target_os = "macos"),
235-
target_pointer_width = "64",
236-
target_endian = "little"
237-
)) {
238-
unimplemented!(
239-
"GenMC is disabled, cannot handle argument: \"-Zmiri-genmc{trimmed_arg}\""
240-
);
230+
pub fn parse_arg(
231+
_genmc_config: &mut Option<GenmcConfig>,
232+
trimmed_arg: &str,
233+
) -> Result<(), String> {
234+
if cfg!(feature = "genmc") {
235+
Err(format!("GenMC is disabled in this build of Miri"))
241236
} else {
242-
unimplemented!(
243-
"GenMC mode is not supported on this platform, cannot handle argument: \"-Zmiri-genmc{trimmed_arg}\""
244-
);
237+
Err(format!("GenMC is not supported on this target"))
245238
}
246239
}
247240

src/concurrency/thread.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,8 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
677677
fn run_on_stack_empty(&mut self) -> InterpResult<'tcx, Poll<()>> {
678678
let this = self.eval_context_mut();
679679
// Inform GenMC that a thread has finished all user code. GenMC needs to know this for scheduling.
680+
// FIXME(GenMC): Thread-local destructors *are* user code, so this is odd. Also now that we
681+
// support pre-main constructors, it can get called there as well.
680682
if let Some(genmc_ctx) = this.machine.data_race.as_genmc_ref() {
681683
let thread_id = this.active_thread();
682684
genmc_ctx.handle_thread_stack_empty(thread_id);

tests/genmc/pass/test_cxx_build.stderr

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
warning: Borrow tracking has been disabled, it is not (yet) supported in GenMC mode.
2-
1+
warning: borrow tracking has been disabled, it is not (yet) supported in GenMC mode.
32
C++: GenMC handle created!
43
Miri: GenMC handle creation successful!
54
C++: GenMC handle destroyed!

0 commit comments

Comments
 (0)