Stream: t-lang/wg-unsafe-code-guidelines

Topic: fn pointer Debug vs Stacked Borrows


Jake Goulding (Apr 23 2019 at 01:53, on Zulip):
fn test_fn() {
    println!("Hello!");
}

#[derive(Debug)]
pub struct FunctionHolder {
    function: fn(),
}

impl FunctionHolder {
    pub fn new() -> Self {
        FunctionHolder { function: test_fn }
    }
}

fn main() {
    let f0 = FunctionHolder::new();
    println!("{:?}", f0);
}
error[E0080]: constant evaluation error: attempted to do invalid arithmetic on pointers that would leak base addresses, e.g., comparing pointers into different allocations
   --> /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/cmp.rs:978:52
    |
978 |                 fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
    |                                                    ^^^^^^^^^^^^^^^^^^^ attempted to do invalid arithmetic on pointers that would leak base addresses, e.g., comparing pointers into different allocations
    |
    = note: inside call to `std::cmp::impls::<impl std::cmp::PartialOrd for usize>::ge` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/fmt/num.rs:53:30
    = note: inside call to `<core::fmt::num::LowerHex as core::fmt::num::GenericRadix>::fmt_int::<usize>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/fmt/num.rs:135:46
    = note: inside call to `core::fmt::num::<impl std::fmt::LowerHex for usize>::fmt` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/fmt/mod.rs:2024:19
    = note: inside call to `<*const () as std::fmt::Pointer>::fmt` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/ptr.rs:2634:17
    = note: inside call to `std::ptr::<impl std::fmt::Debug for fn()>::fmt` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/fmt/mod.rs:1914:81
    = note: inside call to `<&fn() as std::fmt::Debug>::fmt` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/fmt/builders.rs:146:17
    = note: inside call to closure at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/result.rs:639:22
    = note: inside call to `std::result::Result::<(), std::fmt::Error>::and_then::<(), [closure@DefId(2/1:2376 ~ core[6458]::fmt[0]::builders[0]::{{impl}}[2]::field[0]::{{closure}}[0]) 0:&mut &mut std::fmt::DebugStruct, 1:&&str, 2:&&dyn std::fmt::Debug]>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/fmt/builders.rs:130:23
note: inside call to `std::fmt::DebugStruct::field` at src/main.rs:5:10
   --> src/main.rs:5:10
    |
5   | #[derive(Debug)]
    |          ^^^^^
    = note: inside call to `<FunctionHolder as std::fmt::Debug>::fmt` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/fmt/mod.rs:1016:17
    = note: inside call to `std::fmt::write` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/io/mod.rs:1279:15
    = note: inside call to `<std::io::StdoutLock as std::io::Write>::write_fmt` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/io/stdio.rs:533:9
    = note: inside call to `<std::io::Stdout as std::io::Write>::write_fmt` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/io/stdio.rs:786:9
    = note: inside call to closure at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/thread/local.rs:299:16
    = note: inside call to `std::thread::LocalKey::<std::cell::RefCell<std::option::Option<std::boxed::Box<dyn std::io::Write + std::marker::Send>>>>::try_with::<[closure@DefId(1/1:1027 ~ std[82ff]::io[0]::stdio[0]::print_to[0]::{{closure}}[0]) 0:&std::fmt::Arguments, 1:&fn() -> std::io::Stdout], std::result::Result<(), std::io::Error>>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/io/stdio.rs:780:18
    = note: inside call to `std::io::stdio::print_to::<std::io::Stdout>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/io/stdio.rs:802:5
note: inside call to `std::io::_print` at <::std::macros::println macros>:2:3
   --> src/main.rs:18:5
    |
18  |     println!("{:?}", f0);
    |     ^^^^^^^^^^^^^^^^^^^^^
    = note: inside call to `main` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/rt.rs:64:34
    = note: inside call to closure at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/rt.rs:52:53
    = note: inside call to closure at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/panicking.rs:293:40
    = note: inside call to `std::panicking::try::do_call::<[closure@DefId(1/1:1834 ~ std[82ff]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe], i32>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/panicking.rs:289:5
    = note: inside call to `std::panicking::try::<i32, [closure@DefId(1/1:1834 ~ std[82ff]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe]>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/panic.rs:388:9
    = note: inside call to `std::panic::catch_unwind::<[closure@DefId(1/1:1834 ~ std[82ff]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe], i32>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/rt.rs:52:25
    = note: inside call to `std::rt::lang_start_internal` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/rt.rs:64:5
    = note: inside call to `std::rt::lang_start::<()>`
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

/cc @RalfJ ^

RalfJ (Apr 23 2019 at 16:03, on Zulip):

This has nothing to do with Stacked Borrows. You cannot print pointers in Miri.

RalfJ (Apr 23 2019 at 20:03, on Zulip):

@Jake Goulding basically Miri does not actually pick integer base addresses for allocations, it keeps them abstract to make execution deterministic. so whenever program behavior actually depends on that choice, Miri aborts.

RalfJ (Apr 23 2019 at 20:03, on Zulip):

see https://github.com/rust-lang/miri/issues/224 for the way we plan to fix this, eventually

Jake Goulding (Apr 24 2019 at 00:42, on Zulip):

@RalfJ Sure, but is Miri "right" or "wrong" here?

RalfJ (Apr 24 2019 at 07:15, on Zulip):

the message doesn't mean "this is UB", it means "this program does stuff nit supported by Miri"

RalfJ (Apr 24 2019 at 07:15, on Zulip):

(we have a long-standing open issue to make this classification clearer)

Jake Goulding (Apr 26 2019 at 14:16, on Zulip):

Ohhhhhhhh. TIL

Last update: Nov 19 2019 at 18:40UTC