Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect error message for offset_from() on pointers to two different allocations. #4143

Closed
theemathas opened this issue Jan 21, 2025 · 2 comments · Fixed by rust-lang/rust#136438
Labels
A-diagnostics errors and warnings emitted by miri A-intrinsics Area: Affects out implementation of Rust intrinsics C-enhancement Category: a PR with an enhancement or an issue tracking an accepted enhancement

Comments

@theemathas
Copy link

theemathas commented Jan 21, 2025

I ran the following code with Miri:

fn main() {
    unsafe {
        (&1_u8 as *const u8).offset_from(&2_u8);
    }
}

I expected Miri to sensibly report some UB, but instead I got the following:

error: Undefined Behavior: out-of-bounds `offset_from` origin: expected a pointer to the end of 4 bytes of memory, but got alloc4 which is at the beginning of the allocation
 --> src/main.rs:3:9
  |
3 |         (&1_u8 as *const u8).offset_from(&2_u8);
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to the end of 4 bytes of memory, but got alloc4 which is at the beginning of the allocation
  |
  = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
  = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
  = note: BACKTRACE:
  = note: inside `main` at src/main.rs:3:9: 3:48

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

The error message doesn't make any sense. I don't know where Miri got the "4 bytes of memory" expectation from. So I think the error is incorrect.

Reproducible on the playground with rust version 1.86.0-nightly (2025-01-20 f3d1d47fd84dfcf7f513)

@theemathas
Copy link
Author

theemathas commented Jan 21, 2025

For some reason, printing the pointer before calling offset_from() causes Miri to expect a very large allocation:

fn main() {
    let x: &u8 = &1_u8;
    println!("{:p}", x);
    unsafe {
        (x as *const u8).offset_from(&2_u8);
    }
}
error: Undefined Behavior: out-of-bounds `offset_from` origin: expected a pointer to the end of 51524 bytes of memory, but got alloc10 which is at the beginning of the allocation
 --> src/main.rs:5:9
  |
5 |         (x as *const u8).offset_from(&2_u8);
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to the end of 51524 bytes of memory, but got alloc10 which is at the beginning of the allocation
  |
  = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
  = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
  = note: BACKTRACE:
  = note: inside `main` at src/main.rs:5:9: 5:44

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

Note the "expected a pointer to the end of 51524 bytes of memory" in the error. I think this indicates that something has gone very wrong inside miri.

@RalfJung
Copy link
Member

The error is confusing but not fundamentally incorrect: the nicest way to check "are these two pointers in the same allocation" that also accounts for edge cases like identical pointers is to check "is the memory range between them dereferenceable from both pointers". That's what Miri is doing, and it's where the "4 bytes of memory" expectation comes from: the two pointers happen to be 4 bytes apart in that case.

I still think that this is the nicest implementation strategy, but we should probably find a way to make the error less confusing.

@RalfJung RalfJung added C-enhancement Category: a PR with an enhancement or an issue tracking an accepted enhancement A-shims Area: This affects the external function shims A-diagnostics errors and warnings emitted by miri A-intrinsics Area: Affects out implementation of Rust intrinsics and removed C-enhancement Category: a PR with an enhancement or an issue tracking an accepted enhancement A-shims Area: This affects the external function shims labels Feb 2, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Feb 3, 2025
Rollup merge of rust-lang#136438 - RalfJung:offset_from_ub_errors, r=oli-obk

miri: improve error when offset_from preconditions are violated

Fixes rust-lang/miri#4143
github-actions bot pushed a commit that referenced this issue Feb 4, 2025
miri: improve error when offset_from preconditions are violated

Fixes #4143
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics errors and warnings emitted by miri A-intrinsics Area: Affects out implementation of Rust intrinsics C-enhancement Category: a PR with an enhancement or an issue tracking an accepted enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants