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

A debug allocator for std #83

Closed
saethlin opened this issue Aug 9, 2022 · 1 comment
Closed

A debug allocator for std #83

saethlin opened this issue Aug 9, 2022 · 1 comment
Labels
api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api

Comments

@saethlin
Copy link
Member

saethlin commented Aug 9, 2022

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.

Solution sketches

rust-lang/rust#99074

Links and related work

@saethlin saethlin added api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api labels Aug 9, 2022
@saethlin
Copy link
Member Author

saethlin commented Oct 5, 2022

Decision in t-libs Zulip was to prove this out in a third-party crate, then based on the results of that experimentation, decide what if anything should be brought into the standard library.

@saethlin saethlin closed this as not planned Won't fix, can't repro, duplicate, stale Oct 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api
Projects
None yet
Development

No branches or pull requests

1 participant