-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Fat pointers with same data part, but different vtables #48795
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
We don't guarantee that vtables are unique. For example, a separate copy could be generated in multiple codegen units, or multiple crates. |
OK. In that case, shouldn't |
Two fat pointers may point to the same data, but with different vtables (the compiler do not guarantee that vtables are unique). Such pointers should be considered equal by std::ptr::eq(), so cast them to thin pointers to compare only their data part. See <rust-lang#48795>.
This also affects slices: use std::ptr;
fn main() {
let array = [1, 2, 3, 4];
let slice1 = &array[0..1];
let slice2 = &array[0..3];
println!("{:p} == {:p} ? {}", slice1, slice2, ptr::eq(slice1, slice2));
}
|
Here is the smallest sample I managed to find to demonstrate this on my system using rustups's 1.27.0-nightly. It appears this is only reproducible with incremental builds, which is why it won't show up when trying it with Rust Playground. use std::path::Path;
pub trait Block { }
struct Inner {
data: i32,
}
impl Block for Inner { }
impl Inner {
fn new_box(data: i32) -> Box<Inner> {
Box::new(Inner {
data: data,
})
}
}
pub struct Outer {
inner: Box<Inner>,
block: *mut Block,
}
impl Outer {
pub fn new_box<P: AsRef<Path>>() -> Box<Outer> {
let mut inner = Inner::new_box(123);
let block = &mut *inner as *mut _;
Box::new(Outer {
inner: inner,
block: block,
})
}
pub fn get_inner(&mut self) -> &mut Block {
&mut *self.inner
}
}
fn main() {
let mut outer = Outer::new_box::<&str>();
let b = outer.block;
let a = outer.get_inner() as *mut Block;
println!("{:p} == {:p}: {}", a, b, a == b);
} Result:
|
I'm being bit by this problem also. It's causing |
Closing as duplicate of #46139. |
I did not manage to reproduce in a minimal sample, but in my application, I ended up with:
printing:
After investigations (and discussion on freenode/##rust), it appeared that
x
andy
were fat pointers having the same data part (the 64 first bits), but a different vtable (the last 64 bits).I applied this patch to my application, which solves the reported issue: Genymobile/gnirehtet@c36fa4d
But I can't understand how two fat pointers for the same objects may have different vtables. Is it expected?
The text was updated successfully, but these errors were encountered: