Description
Proposal
In debug builds, change the default allocator in the standard library to one which helps users find and fix bugs. For the moment I am specifically focusing on alignment bugs.
Problem statement
After aliasing and initialization-related issues, the next most common form of UB detected by Miri is misaligned pointer access. 145 published crates have misaligned pointer access reachable by cargo miri test
(in the presence of Miri's allocator). That means that the authors of these crates are writing tests, but don't know to use Miri to find issues in their unsafe code.
We have rich debug assertions in the standard library which check a lot of code paths for misaligned pointer access, but the default allocator serves up allocations which are over-aligned. So if users are testing their code by allocating Vec<u8>
then casting that pointer to another type, the debug assertions are probably useless for finding alignment bugs.
Motivation, use-cases
Pointer dereferences are UB if not sufficiently aligned. This form of UB is especially latent on x86, and also with common allocators, because a general-purpose high-performance allocator is going to over-align everything. But Rust is used on other architectures and also with alternative allocators like bumpalo
. For example, this program with -Zbuild-std
:
fn main() {
let bump = bumpalo::Bump::new();
let ptr = bump.alloc_str("uwu").as_ptr();
unsafe {
let _: &[u16] = core::slice::from_raw_parts(ptr.cast(), 1);
}
}
Finished dev [unoptimized + debuginfo] target(s) in 12.80s
Running `target/x86_64-unknown-linux-gnu/debug/scratch`
Illegal instruction (core dumped)
But if instead of bumpalo
we used the default allocator on Linux, this program will always be well-defined. So in some sense it's up to interpretation whether code that behaves like this is non-portable or buggy, but in my experience most crate authors believe that their code which does UB when a user swaps out the allocator is buggy.
Extra bug detection powers should be on by default, as much as we can have them. It seems that the users making these mistakes know to write tests, but since they don't know to reach for Miri, it seems unlikely they will reach for another non-default compiler flag. Yes, I am well aware that this will probably end up stuck behind -Zbuild-std
but that itself is fixable, and some parts of the community already use -Zbuild-std
broadly. We can help those users now and perhaps features like this will encourage more contribution to help with -Zbuild-std
.