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

dynptr(&mut) compiles but doesn’t work #103

Open
numberZero opened this issue Feb 27, 2025 · 1 comment
Open

dynptr(&mut) compiles but doesn’t work #103

numberZero opened this issue Feb 27, 2025 · 1 comment

Comments

@numberZero
Copy link

E.g. in this small example the assertion fails:

#[stabby::stabby]
pub trait Iface {
    extern "C" fn set(&mut self, val: i32);
}

struct Impl {
    cookie: i32,
}

impl Iface for Impl {
    extern "C" fn set(&mut self, val: i32) {
        println!("set({:?}, {})", self as *mut _, val);
        self.cookie = val;
    }
}

fn main() {
    let mut val = Impl { cookie: 42 };
    println!("val is at {:?}", (&val) as *const _);
    let mut ptr: stabby::dynptr!(&'_ mut dyn Iface) = (&mut val).into();
    println!("ptr is at {:?}", (&ptr) as *const _);
    ptr.set(13);
    drop(ptr);
    assert_eq!(val.cookie, 13);
}

The output is suspicious:

val is at 0x7fffd73e8f54
ptr is at 0x7fffd73e8fb0
set(0x7fffd73e8fb0, 13)
thread 'main' panicked at src/main.rs:24:5:
assertion `left == right` failed
  left: 42
 right: 13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Apparently somehow, pointer to ptr instead of its value is passed to set.

Versions

stabby 36.2.2
rustc 1.84.0 (9fc6b4312 2025-01-07)

@numberZero
Copy link
Author

...and this example downright crashes with a segmentation fault:

#[stabby::stabby]
pub trait Iface {
    extern "C" fn strike(&mut self);
}

#[repr(C)]
struct Victim<'a> {
    ptr: stabby::dynptr!(&'a mut dyn Iface),
    target: Box<u8>,
}

#[repr(C)]
struct Attack {
    pad1: isize,
    pad2: isize,
    target: isize,
}

impl Iface for Attack {
    extern "C" fn strike(&mut self) {
        self.target = 0;
    }
}

fn main() {
    let mut val = Attack {
        pad1: 0,
        pad2: 0,
        target: 0,
    };
    let mut vic = Victim {
        ptr: (&mut val).into(),
        target: Box::new(42),
    };
    vic.ptr.strike();
    println!("The answer is {}", vic.target);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant