Skip to content

Commit d6f9435

Browse files
authored
Merge pull request #4418 from RalfJung/native-lib-tracing
various minor native-lib-tracing tweaks
2 parents 96a70e2 + 5e14d0f commit d6f9435

File tree

15 files changed

+305
-345
lines changed

15 files changed

+305
-345
lines changed

src/tools/miri/README.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -419,11 +419,9 @@ to Miri failing to detect cases of undefined behavior in a program.
419419
Finally, the flag is **unsound** in the sense that Miri stops tracking details such as
420420
initialization and provenance on memory shared with native code, so it is easily possible to write
421421
code that has UB which is missed by Miri.
422-
* `-Zmiri-force-old-native-lib-mode` disables the WIP improved native code access tracking. If for
423-
whatever reason enabling native calls leads to odd behaviours or causes Miri to panic, disabling
424-
the tracer *might* fix this. This will likely be removed once the tracer has been adequately
425-
battle-tested. Note that this flag is only meaningful on Linux systems; other Unixes (currently)
426-
exclusively use the old native-lib code.
422+
* `-Zmiri-native-lib-enable-tracing` enables the WIP detailed tracing mode for invoking native code.
423+
Note that this flag is only meaningful on Linux systems; other Unixes (currently) do not support
424+
tracing mode.
427425
* `-Zmiri-measureme=<name>` enables `measureme` profiling for the interpreted program.
428426
This can be used to find which parts of your program are executing slowly under Miri.
429427
The profile is written out to a file inside a directory called `<name>`, and can be processed

src/tools/miri/src/alloc/isolated_alloc.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,12 +305,12 @@ impl IsolatedAlloc {
305305
/// Returns a vector of page addresses managed by the allocator.
306306
pub fn pages(&self) -> Vec<usize> {
307307
let mut pages: Vec<usize> =
308-
self.page_ptrs.clone().into_iter().map(|p| p.expose_provenance().get()).collect();
309-
self.huge_ptrs.iter().for_each(|(ptr, size)| {
308+
self.page_ptrs.iter().map(|p| p.expose_provenance().get()).collect();
309+
for (ptr, size) in self.huge_ptrs.iter() {
310310
for i in 0..size / self.page_size {
311311
pages.push(ptr.expose_provenance().get().strict_add(i * self.page_size));
312312
}
313-
});
313+
}
314314
pages
315315
}
316316

src/tools/miri/src/bin/miri.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
228228
let return_code = miri::eval_entry(tcx, entry_def_id, entry_type, &config, None)
229229
.unwrap_or_else(|| {
230230
#[cfg(target_os = "linux")]
231-
miri::register_retcode_sv(rustc_driver::EXIT_FAILURE);
231+
miri::native_lib::register_retcode_sv(rustc_driver::EXIT_FAILURE);
232232
tcx.dcx().abort_if_errors();
233233
rustc_driver::EXIT_FAILURE
234234
});
@@ -724,8 +724,8 @@ fn main() {
724724
} else {
725725
show_error!("-Zmiri-native-lib `{}` does not exist", filename);
726726
}
727-
} else if arg == "-Zmiri-force-old-native-lib-mode" {
728-
miri_config.force_old_native_lib = true;
727+
} else if arg == "-Zmiri-native-lib-enable-tracing" {
728+
miri_config.native_lib_enable_tracing = true;
729729
} else if let Some(param) = arg.strip_prefix("-Zmiri-num-cpus=") {
730730
let num_cpus = param
731731
.parse::<u32>()
@@ -797,14 +797,14 @@ fn main() {
797797
debug!("rustc arguments: {:?}", rustc_args);
798798
debug!("crate arguments: {:?}", miri_config.args);
799799
#[cfg(target_os = "linux")]
800-
if !miri_config.native_lib.is_empty() && !miri_config.force_old_native_lib {
800+
if !miri_config.native_lib.is_empty() && miri_config.native_lib_enable_tracing {
801801
// FIXME: This should display a diagnostic / warning on error
802802
// SAFETY: If any other threads exist at this point (namely for the ctrlc
803803
// handler), they will not interact with anything on the main rustc/Miri
804804
// thread in an async-signal-unsafe way such as by accessing shared
805805
// semaphores, etc.; the handler only calls `sleep()` and `exit()`, which
806806
// are async-signal-safe, as is accessing atomics
807-
let _ = unsafe { miri::init_sv() };
807+
let _ = unsafe { miri::native_lib::init_sv() };
808808
}
809809
run_compiler_and_exit(
810810
&rustc_args,

src/tools/miri/src/diagnostics.rs

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,9 @@ pub enum NonHaltingDiagnostic {
132132
Int2Ptr {
133133
details: bool,
134134
},
135-
NativeCallSharedMem,
136-
NativeCallNoTrace,
135+
NativeCallSharedMem {
136+
tracing: bool,
137+
},
137138
WeakMemoryOutdatedLoad {
138139
ptr: Pointer,
139140
},
@@ -628,10 +629,8 @@ impl<'tcx> MiriMachine<'tcx> {
628629
RejectedIsolatedOp(_) =>
629630
("operation rejected by isolation".to_string(), DiagLevel::Warning),
630631
Int2Ptr { .. } => ("integer-to-pointer cast".to_string(), DiagLevel::Warning),
631-
NativeCallSharedMem =>
632+
NativeCallSharedMem { .. } =>
632633
("sharing memory with a native function".to_string(), DiagLevel::Warning),
633-
NativeCallNoTrace =>
634-
("unable to trace native code memory accesses".to_string(), DiagLevel::Warning),
635634
ExternTypeReborrow =>
636635
("reborrow of reference to `extern type`".to_string(), DiagLevel::Warning),
637636
CreatedPointerTag(..)
@@ -666,11 +665,8 @@ impl<'tcx> MiriMachine<'tcx> {
666665
ProgressReport { .. } =>
667666
format!("progress report: current operation being executed is here"),
668667
Int2Ptr { .. } => format!("integer-to-pointer cast"),
669-
NativeCallSharedMem => format!("sharing memory with a native function called via FFI"),
670-
NativeCallNoTrace =>
671-
format!(
672-
"sharing memory with a native function called via FFI, and unable to use ptrace"
673-
),
668+
NativeCallSharedMem { .. } =>
669+
format!("sharing memory with a native function called via FFI"),
674670
WeakMemoryOutdatedLoad { ptr } =>
675671
format!("weak memory emulation: outdated value returned from load at {ptr}"),
676672
ExternTypeReborrow =>
@@ -716,42 +712,41 @@ impl<'tcx> MiriMachine<'tcx> {
716712
}
717713
v
718714
}
719-
NativeCallSharedMem => {
720-
vec![
721-
note!(
722-
"when memory is shared with a native function call, Miri can only track initialisation and provenance on a best-effort basis"
723-
),
724-
note!(
725-
"in particular, Miri assumes that the native call initializes all memory it has written to"
726-
),
727-
note!(
728-
"Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory"
729-
),
730-
note!(
731-
"what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free"
732-
),
733-
]
734-
}
735-
NativeCallNoTrace => {
736-
vec![
737-
note!(
738-
"when memory is shared with a native function call, Miri stops tracking initialization and provenance for that memory"
739-
),
740-
note!(
741-
"in particular, Miri assumes that the native call initializes all memory it has access to"
742-
),
743-
note!(
744-
"Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory"
745-
),
746-
note!(
747-
"what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free"
748-
),
749-
#[cfg(target_os = "linux")]
750-
note!(
751-
"this is normally partially mitigated, but either -Zmiri-force-old-native-lib-mode was passed or ptrace is disabled on your system"
752-
),
753-
]
754-
}
715+
NativeCallSharedMem { tracing } =>
716+
if *tracing {
717+
vec![
718+
note!(
719+
"when memory is shared with a native function call, Miri can only track initialisation and provenance on a best-effort basis"
720+
),
721+
note!(
722+
"in particular, Miri assumes that the native call initializes all memory it has written to"
723+
),
724+
note!(
725+
"Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory"
726+
),
727+
note!(
728+
"what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free"
729+
),
730+
note!(
731+
"tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here"
732+
),
733+
]
734+
} else {
735+
vec![
736+
note!(
737+
"when memory is shared with a native function call, Miri stops tracking initialization and provenance for that memory"
738+
),
739+
note!(
740+
"in particular, Miri assumes that the native call initializes all memory it has access to"
741+
),
742+
note!(
743+
"Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory"
744+
),
745+
note!(
746+
"what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free"
747+
),
748+
]
749+
},
755750
ExternTypeReborrow => {
756751
assert!(self.borrow_tracker.as_ref().is_some_and(|b| {
757752
matches!(

src/tools/miri/src/eval.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ pub struct MiriConfig {
150150
pub retag_fields: RetagFields,
151151
/// The location of the shared object files to load when calling external functions
152152
pub native_lib: Vec<PathBuf>,
153-
/// Whether to force using the old native lib behaviour even if ptrace might be supported.
154-
pub force_old_native_lib: bool,
153+
/// Whether to enable the new native lib tracing system.
154+
pub native_lib_enable_tracing: bool,
155155
/// Run a garbage collector for BorTags every N basic blocks.
156156
pub gc_interval: u32,
157157
/// The number of CPUs to be reported by miri.
@@ -201,7 +201,7 @@ impl Default for MiriConfig {
201201
report_progress: None,
202202
retag_fields: RetagFields::Yes,
203203
native_lib: vec![],
204-
force_old_native_lib: false,
204+
native_lib_enable_tracing: false,
205205
gc_interval: 10_000,
206206
num_cpus: 1,
207207
page_size: None,

src/tools/miri/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ use rustc_middle::{bug, span_bug};
100100
use tracing::{info, trace};
101101

102102
#[cfg(target_os = "linux")]
103-
pub use crate::shims::trace::{init_sv, register_retcode_sv};
103+
pub mod native_lib {
104+
pub use crate::shims::{init_sv, register_retcode_sv};
105+
}
104106

105107
// Type aliases that set the provenance parameter.
106108
pub type Pointer = interpret::Pointer<Option<machine::Provenance>>;

src/tools/miri/src/shims/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ pub mod os_str;
1919
pub mod panic;
2020
pub mod time;
2121
pub mod tls;
22-
#[cfg(target_os = "linux")]
23-
pub mod trace;
2422

2523
pub use self::files::FdTable;
24+
#[cfg(target_os = "linux")]
25+
pub use self::native_lib::trace::{init_sv, register_retcode_sv};
2626
pub use self::unix::{DirTable, EpollInterestTable};
2727

2828
/// What needs to be done after emulating an item (a shim or an intrinsic) is done.

0 commit comments

Comments
 (0)