Skip to content

Commit e7ab430

Browse files
committed
Auto merge of #1332 - RalfJung:disable-alignment-check, r=RalfJung
Add option to disable alignment check Requires rust-lang/rust#71101 Fixes #1326
2 parents df0e32c + 8e73db6 commit e7ab430

File tree

8 files changed

+69
-27
lines changed

8 files changed

+69
-27
lines changed

README.md

+31-23
Original file line numberDiff line numberDiff line change
@@ -165,43 +165,51 @@ up the sysroot. If you are using `miri` (the Miri driver) directly, see
165165
## Miri `-Z` flags and environment variables
166166
[miri-flags]: #miri--z-flags-and-environment-variables
167167

168-
Several `-Z` flags are relevant for Miri:
169-
170-
* `-Zmiri-seed=<hex>` is a custom `-Z` flag added by Miri. It configures the
171-
seed of the RNG that Miri uses to resolve non-determinism. This RNG is used
172-
to pick base addresses for allocations. When isolation is enabled (the default),
173-
this is also used to emulate system entropy. The default seed is 0.
174-
**NOTE**: This entropy is not good enough for cryptographic use! Do not
175-
generate secret keys in Miri or perform other kinds of cryptographic
176-
operations that rely on proper random numbers.
177-
* `-Zmiri-disable-validation` disables enforcing validity invariants, which are
178-
enforced by default. This is mostly useful for debugging. It means Miri will
179-
miss bugs in your program. However, this can also help to make Miri run
180-
faster.
168+
Miri adds its own set of `-Z` flags:
169+
170+
* `-Zmiri-disable-alignment-check` disables checking pointer alignment. This is
171+
useful to avoid [false positives][alignment-false-positives]. However, setting
172+
this flag means Miri could miss bugs in your program.
181173
* `-Zmiri-disable-stacked-borrows` disables checking the experimental
182174
[Stacked Borrows] aliasing rules. This can make Miri run faster, but it also
183175
means no aliasing violations will be detected.
176+
* `-Zmiri-disable-validation` disables enforcing validity invariants, which are
177+
enforced by default. This is mostly useful to focus on other failures (such
178+
as out-of-bounds accesses) first. Setting this flag means Miri will miss bugs
179+
in your program. However, this can also help to make Miri run faster.
184180
* `-Zmiri-disable-isolation` disables host isolation. As a consequence,
185181
the program has access to host resources such as environment variables, file
186182
systems, and randomness.
187-
* `-Zmiri-ignore-leaks` disables the memory leak checker.
188183
* `-Zmiri-env-exclude=<var>` keeps the `var` environment variable isolated from
189-
the host. Can be used multiple times to exclude several variables. The `TERM`
190-
environment variable is excluded by default.
184+
the host so that it cannot be accessed by the program. Can be used multiple
185+
times to exclude several variables. On Windows, the `TERM` environment
186+
variable is excluded by default.
187+
* `-Zmiri-ignore-leaks` disables the memory leak checker.
188+
* `-Zmiri-seed=<hex>` configures the seed of the RNG that Miri uses to resolve
189+
non-determinism. This RNG is used to pick base addresses for allocations.
190+
When isolation is enabled (the default), this is also used to emulate system
191+
entropy. The default seed is 0. **NOTE**: This entropy is not good enough
192+
for cryptographic use! Do not generate secret keys in Miri or perform other
193+
kinds of cryptographic operations that rely on proper random numbers.
194+
* `-Zmiri-track-alloc-id=<id>` shows a backtrace when the given allocation is
195+
being allocated. This helps in debugging memory leaks.
196+
* `-Zmiri-track-pointer-tag=<tag>` shows a backtrace when the given pointer tag
197+
is popped from a borrow stack (which is where the tag becomes invalid and any
198+
future use of it will error). This helps you in finding out why UB is
199+
happening and where in your code would be a good place to look for it.
200+
201+
[alignment-false-positives]: https://github.com/rust-lang/miri/issues/1074
202+
203+
Some native rustc `-Z` flags are also very relevant for Miri:
204+
191205
* `-Zmir-opt-level` controls how many MIR optimizations are performed. Miri
192206
overrides the default to be `0`; be advised that using any higher level can
193207
make Miri miss bugs in your program because they got optimized away.
194208
* `-Zalways-encode-mir` makes rustc dump MIR even for completely monomorphic
195209
functions. This is needed so that Miri can execute such functions, so Miri
196210
sets this flag per default.
197211
* `-Zmir-emit-retag` controls whether `Retag` statements are emitted. Miri
198-
enables this per default because it is needed for validation.
199-
* `-Zmiri-track-pointer-tag=<tag>` shows a backtrace when the given pointer tag
200-
is popped from a borrow stack (which is where the tag becomes invalid and any
201-
future use of it will error). This helps you in finding out why UB is
202-
happening and where in your code would be a good place to look for it.
203-
* `-Zmiri-track-alloc-id=<id>` shows a backtrace when the given allocation is
204-
being allocated. This helps in debugging memory leaks.
212+
enables this per default because it is needed for [Stacked Borrows].
205213

206214
Moreover, Miri recognizes some environment variables:
207215

rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4d1fbaccb822b6d52dc786589de7918d3c5effb1
1+
47f49695dfb4fe9e584239fdc59c771887148a57

src/bin/miri.rs

+5
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ fn main() {
128128
// Parse our arguments and split them across `rustc` and `miri`.
129129
let mut validate = true;
130130
let mut stacked_borrows = true;
131+
let mut check_alignment = true;
131132
let mut communicate = false;
132133
let mut ignore_leaks = false;
133134
let mut seed: Option<u64> = None;
@@ -152,6 +153,9 @@ fn main() {
152153
"-Zmiri-disable-stacked-borrows" => {
153154
stacked_borrows = false;
154155
}
156+
"-Zmiri-disable-alignment-check" => {
157+
check_alignment = false;
158+
}
155159
"-Zmiri-disable-isolation" => {
156160
communicate = true;
157161
}
@@ -243,6 +247,7 @@ fn main() {
243247
let miri_config = miri::MiriConfig {
244248
validate,
245249
stacked_borrows,
250+
check_alignment,
246251
communicate,
247252
ignore_leaks,
248253
excluded_env_vars,

src/diagnostics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ pub fn report_error<'tcx, 'mir>(
9797
vec![
9898
format!("this usually indicates that your program performed an invalid operation and caused Undefined Behavior"),
9999
format!("but alignment errors can also be false positives, see https://github.com/rust-lang/miri/issues/1074"),
100+
format!("you can disable the alignment check with `-Zmiri-disable-alignment-check`, but that could hide true bugs")
100101
],
101102
UndefinedBehavior(_) =>
102103
vec![

src/eval.rs

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ pub struct MiriConfig {
1919
pub validate: bool,
2020
/// Determines if Stacked Borrows is enabled.
2121
pub stacked_borrows: bool,
22+
/// Determines if alignment checking is enabled.
23+
pub check_alignment: bool,
2224
/// Determines if communication with the host environment is enabled.
2325
pub communicate: bool,
2426
/// Determines if memory leaks should be ignored.
@@ -40,6 +42,7 @@ impl Default for MiriConfig {
4042
MiriConfig {
4143
validate: true,
4244
stacked_borrows: true,
45+
check_alignment: true,
4346
communicate: false,
4447
ignore_leaks: false,
4548
excluded_env_vars: vec![],
@@ -72,6 +75,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
7275
config.stacked_borrows,
7376
config.tracked_pointer_tag,
7477
config.tracked_alloc_id,
78+
config.check_alignment,
7579
),
7680
);
7781
// Complete initialization.

src/machine.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,19 @@ pub struct MemoryExtra {
118118
/// An allocation ID to report when it is being allocated
119119
/// (helps for debugging memory leaks).
120120
tracked_alloc_id: Option<AllocId>,
121+
122+
/// Controls whether alignment of memory accesses is being checked.
123+
check_alignment: bool,
121124
}
122125

123126
impl MemoryExtra {
124-
pub fn new(rng: StdRng, stacked_borrows: bool, tracked_pointer_tag: Option<PtrId>, tracked_alloc_id: Option<AllocId>) -> Self {
127+
pub fn new(
128+
rng: StdRng,
129+
stacked_borrows: bool,
130+
tracked_pointer_tag: Option<PtrId>,
131+
tracked_alloc_id: Option<AllocId>,
132+
check_alignment: bool,
133+
) -> Self {
125134
let stacked_borrows = if stacked_borrows {
126135
Some(Rc::new(RefCell::new(stacked_borrows::GlobalState::new(tracked_pointer_tag))))
127136
} else {
@@ -133,6 +142,7 @@ impl MemoryExtra {
133142
extern_statics: FxHashMap::default(),
134143
rng: RefCell::new(rng),
135144
tracked_alloc_id,
145+
check_alignment,
136146
}
137147
}
138148

@@ -299,7 +309,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
299309

300310
const GLOBAL_KIND: Option<MiriMemoryKind> = Some(MiriMemoryKind::Global);
301311

302-
const CHECK_ALIGN: bool = true;
312+
#[inline(always)]
313+
fn enforce_alignment(memory_extra: &MemoryExtra) -> bool {
314+
memory_extra.check_alignment
315+
}
303316

304317
#[inline(always)]
305318
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {

tests/compile-fail/unaligned_pointers/alignment.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ fn main() {
22
// miri always gives allocations the worst possible alignment, so a `u8` array is guaranteed
33
// to be at the virtual location 1 (so one byte offset from the ultimate alignemnt location 0)
44
let mut x = [0u8; 20];
5-
let x_ptr: *mut u8 = &mut x[0];
5+
let x_ptr: *mut u8 = x.as_mut_ptr();
66
let y_ptr = x_ptr as *mut u64;
77
unsafe {
88
*y_ptr = 42; //~ ERROR accessing memory with alignment 1, but alignment
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// compile-flags: -Zmiri-disable-alignment-check
2+
3+
fn main() {
4+
let mut x = [0u8; 20];
5+
let x_ptr: *mut u8 = x.as_mut_ptr();
6+
// At least one of these is definitely unaligned.
7+
unsafe {
8+
*(x_ptr as *mut u64) = 42;
9+
*(x_ptr.add(1) as *mut u64) = 42;
10+
}
11+
}

0 commit comments

Comments
 (0)