kvark / copyless

[deprecated] Avoid memcpy calls when working with standard containers
Apache License 2.0
276 stars 12 forks source link

Memory issue with zero-sized types #7

Closed eun-ice closed 5 years ago

eun-ice commented 5 years ago

I have a serious issue I cannot explain. My guess is that copyless creates some sort of memory issue when called with static functions.

assume the following traits:

pub struct Runnable {
    runnable_box: Box<RunnableBox + Send>
}

impl Runnable {
    pub fn run(self) {
        self.runnable_box.run();
    }
}

trait RunnableBox {
    fn run(self: Box<Self>);
}

impl<F: FnOnce()> RunnableBox for F {
    fn run(self: Box<F>) {
        (*self)()
    }
}

And these two constructors, one using Box::new, the other using Box::alloc().init

impl Runnable {
    pub fn new_box<F>(func: F) -> Runnable
        where
            F: FnOnce() + Send + 'static {
        Runnable { runnable_box: Box::new(func) }
    }
    #[allow(dead_code)]
    pub fn new_copyless<F>(func: F) -> Runnable
        where
            F: FnOnce() + Send + 'static {
        Runnable { runnable_box: Box::alloc().init(func) }
    }
}

Creating a static Runnable seems to create some sort of memory overwrite I cannot exactly pin down:

Runnable::new_box(move || { println!("scheduled task 1"); }); // Works

Runnable::new_copyless(move || { println!("scheduled task 1"); }) // Error

let now = Instant::now();
Runnable::new_copyless(move || { println!("scheduled task 1 {:?}", now); }) // Works

I have attached a testcase that fails on macos and on linux using Rust 1.33 stable and rustc 1.35.0-nightly (0576ac109 2019-03-24).

copyless.tar.gz

eun-ice commented 5 years ago

This PR seems to fix the issue: https://github.com/kvark/copyless/pull/8

eun-ice commented 5 years ago

Closing this issue since #8 has been merged. Will investigate and reopen if this issue pops up again. Thank you @kvark