EXC_BAD_ACCESS using c_void from a thread

I am writing a small library in Rust, initially for use from a C++ app.
I am storing callbacks (function pointer + userdata context pointer as c_void), which are set from the C++ app and called from the Rust lib. In this case, userdata refers to a C++ object.

I can call the callback fine from the main thread. However, the library runs a timer on a thread, which is where the callbacks need to be called from. Once I moved the callback call into the timer, I got an exception because the *mut c_void pointer has become null. I can clearly see now, calling the callback outside the thread is fine, inside the thread, it crashes.

The crash happens specifically, if I try and access this within the C++ callback.

Below is simplified code from the library.

#[no_mangle]  
pub type StatsCallback = extern "C" fn(stats: Statistics, caller: *mut c_void);

#[repr(C)]
pub struct StatsCallbackStore {
    pub callback: StatsCallback,
    userdata: *mut c_void,
}

impl StatsCallbackStore {
    pub fn call(&self, stats: Statistics) {
        (self.callback)(stats, self.userdata)
    }
}

pub struct SerialConnection
{
    pub stats_callback_store: Option<StatsCallbackStore>,
}

impl SerialConnection
{
    //...
    pub fn start_receiving(&mut self)
    {
        //...
        let (timer_tx, timer_rx) = channel();

        // Spawn one second timer
        thread::spawn(move || {
            loop {
                thread::sleep(Duration::from_secs(1));
                timer_tx.send(true).unwrap();
            }
        });

        loop {
            // Grab some data from a serial port
            let _ = timer_rx.try_recv().map(|reply| {
                if reply {
                    println!("reply!");
                    // Process data and post to callback

                    match self.stats_callback_store.as_ref() {
                        Some(callback_store) => {
                            // EXC_BAD_ACCESS in here if it tries to 
                            // access `userdata` (`this` on the C++ side)
                            callback_store.call(stats); 
                        }
                        None => {}
                    }

                    line_count = 0;
                }
            });
        }
    }
}


I have started constructing a simplified example but even that is a little complex due to the C++/Rust interop. So I'm asking here in case anyone has a clue, and if it makes sense I will continue and post a simple example project.

OK, this was a problem on the C++ side - the callback was being created on the stack and deallocated which is why it became NULL!! I was writing the code as if the Rust side would take ownership of the callback...