Creating a reference from a pointer UB

I create a reference from a pointer and try to write data over it, but it looks like I'm getting a UB going on.

// Allocs 4096 bytes
let slab_ptr: *mut u8 = self.memory_backend.alloc_slab(self.slab_size);

// Calculates ptr for SlabInfo
// SlabInfo is placed at the end of the allocated SLAB
let slab_info_ptr: *mut SlabInfo = ...

assert_eq!(slab_info_ptr as usize % align_of::<SlabInfo<T>>(), 0, "SlabInfo addr not aligned!");
println!("slab_ptr: {:?}", slab_ptr); // 0x1d66e7d9000
println!("slab_info_ptr: {:?}", slab_info_ptr); // 0x1d66e7d9fd0
println!("slab_info_ptr aligned: {:?}", (slab_info_ptr as usize % align_of::<SlabInfo<T>>()) == 0); // true
println!("slab_info_size: {}", size_of::<SlabInfo<T>>()); // 48
println!("memory used by slab_info: {}", slab_ptr as usize + self.slab_size - slab_info_ptr as usize); // 48

// Make SlabInfo ref
let slab_info_ref: &mut SlabInfo = unsafe { &mut *slab_info_ptr };

*slab_info_ref = SlabInfo {
    ....
};

If I try to write 48 bytes(SlabInfo size) to slab_info_ptr before println(), the whole code works successfully.
This whole piece works 2 times, the first time it works and the second time it doesn't.

I suspect that the compiler is doing something with its optimizations. I tried to run the debugger, but it seems to work incorrectly. I'm pretty sure the problem occurs in this location, as the code behind it is not executing.
opt-level = 0 did not help.

Try running with miri.

You can't construct a reference to uninitialized memory, and definitely not do *ptr = v as that'll drop the old value.

1 Like

So I should to initialize the memory before creating a reference to it?

Yes, and use ptr::write().

1 Like

Could you help me find a place in the documentation that says that? I can't find it.

https://doc.rust-lang.org/1.82.0/core/primitive.pointer.html

Storing through a raw pointer using *ptr = data calls drop on the old value, so write must be used if the type has drop glue and memory is not already initialized - otherwise drop would be called on the uninitialized memory.

5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.