-
Notifications
You must be signed in to change notification settings - Fork 16
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
Allocator::deallocate
causes Miri stacked borrows violation
#193
Comments
This comment was marked as off-topic.
This comment was marked as off-topic.
I'll have to look at the details of those proposed solutions, but can give some context here
Of course I initially tried to run miri without any extra flags, and it failed with basically this error. So I asked in the zullip which confirmed that stacked borrows just cannot deal with allocators (if you also want the ergonomics of references to your allocated values). I think we really do want the ergonomics of slices if we at all can (for bounds checking, stdlib support, etc). At that point I went with just passing
My (naive) assumption has been that miri + tree borrows being OK with the code means that the code is sound. I believe the problem in your second comment is distinct, because I recently ran into something very similar on the |
Thanks for the context about Miri.
I think that may be true, indeed the suggestions I've granted either de-optimize a bit, or sacrifice ergonomics (indeed I'm not 100% sure if the
That's sort-of my reading as well, insofar as Miri claims that tree borrows will find aliasing violations that more tangibly affect Rust today. https://github.com/rust-lang/miri?tab=readme-ov-file#miri--z-flags-and-environment-variables. Though, I still find the allocation pattern we're using somewhat questionable due to deallocating a reference during a function call (i.e.
Ah, I think you're right. I made the comment too fast 😄. I'll look into it more and pull it out into another issue. |
I do believe this is UB, but I will open a separate issue for it. The original topic of this issue is not pertinent, since I won't be using Miri under stacked borrows for this project. |
Miri under defaults settings (e.g.
cargo miri nextest run allocate::tests::unaligned_allocator_16
) generates UB findings for any tests exercising deallocation:This may be real UB, not just a violation of an experimental model. We pass around the allocated memory as a reference. Rust annotates reference function arguments as
dereferencable
, meaning LLVM can infer the reference can always be dereferenced. When a function invokesdeallocate()
, this assumption is violated and is therefore UB (see crossbeam-rs/crossbeam#545 (comment) for a chain of further reading).I believe Miri flags this since we turn the allocated pointer into a reference, then rederive the pointer from the reference. This discards the provenance information about the pointer. We can solve both problems by never decaying allocations to a reference, i.e. always passing around allocations as pointers.
I'd suggest creating a new smart pointer type, perhaps one that encapsulates a raw
*mut u8
andPhantomData<T>
. Here's a quick (bad) sketch of that main...inahga:zlib-rs:inahga/fix-miri.Alternatively, it may be less invasive to return allocations as
NonNull<MaybeUninit<T>>
. I've sketched that as well main...inahga:zlib-rs:inahga/fix-miri-2, it may be tricky to adapt this for slice types though.Relatedly: I see elsewhere in CI we eschew stacked borrow checking by using
-Zmiri-tree-borrows
. What flags should Miri be run under? (I'd prefer that Miri passes with default flags, since it has fairly sensible defaults, but I'm curious if there's any rationale I'm missing).The text was updated successfully, but these errors were encountered: