14

My experimental code crashes when running on bare x86_64-metal (page fault when IDT is not yet set), but works perfectly on aarch64.

By careful tracing I figured out that the cause of this page fault consists of corrupted address (much higher than 0x200_000, while only the first 2M page is yet mapped as 1:1) of function "f" passed as an argument to core::fmt::ArgumentV1::new() function:

#[doc(hidden)]
#[unstable(feature = "fmt_internals", reason = "internal to format_args!")]
pub fn new<'b, T>(x: &'b T,
                  f: fn(&T, &mut Formatter) -> Result) -> ArgumentV1<'b> {
    unsafe {
        ArgumentV1 {
            formatter: mem::transmute(f),
            value: mem::transmute(x)
        }
    }
} 

AFAIK this value is hard-coded by rustc compiler being result of compile-time processing of format_args! variadic arguments.

Maybe you have suggestions what's wrong with this case. Thanks.

ababo
  • 1,490
  • 1
  • 10
  • 24

1 Answers1

1

Quoted from the Rust project's RELEASES.md:

fn item types are zero sized, and each fn names a unique type. This will break code that transmutes fns, so calling transmute on a fn type will generate a warning for a few cycles, then will be converted to an error.

This is part of the release notes for Version 1.9.0 (2016-05-26) so if you are using this version it might be a bug in the std library, if you are on <1.9 you should probably try to copy your code into the playpen and let it generate the assembly so you see where the address actually comes from.

benaryorg
  • 915
  • 1
  • 8
  • 21