You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm integrating a rust library into a c++ binary (via c FFI) and began noticing some very strange behavior. Compiling the c++ code with thread sanitizer indicates potential data races in the rust standard library. I've created a reproducer that triggers the same tsan backtrace for the version we're using (1.39.0), but it also triggers warnings on nightly when building the rust side with thread sanitizer enabled (see Makefile). The code can be found here and run with make && ./main
I've further simplified the interaction by reproducing what I believe to be the same issue in safe Rust (below). Also below is the first tsan warning. I see 2 to 4 warnings from the pure rust version depending on the run.
use std::{
sync::mpsc::{channel, sync_channel,Sender,SyncSender},
thread,};fnmain(){letmut m = Model::new();
m.serve();let s1 = m.new_sender();// These also generate tsan warnings//let s2 = m.new_sender();//let t = thread::spawn(move || {// send_job1(&s2);// Model::delete_sender(s2);//});send_job1(&s1);send_job2(&s1);//let _ = t.join().unwrap();Model::delete_sender(s1);
m.stop();
m.delete();}#[derive(Debug)]structModel{tx:Option<SyncSender<Request>>,iot:Option<thread::JoinHandle<()>>,}#[derive(Debug)]enumRequest{JOB1(),JOB2(Sender<()>),End(Sender<()>),Stop,}implModel{fnnew() -> Self{Model{tx:None,iot:None,}}fndelete(self){}fnserve(&mutself){let(tx, rx) = sync_channel(5);letmut iot_sender = Some(tx.clone());self.tx = Some(tx);self.iot = Some(thread::spawn(move || {for job in rx.iter(){match job {Request::JOB1() => {}Request::JOB2(tx) => {ifletSome(iot_sender) = iot_sender.as_ref(){let _ = iot_sender.send(Request::End(tx));}}Request::End(tx) => {let _ = tx.send(());}Request::Stop => {
iot_sender = None;}}}}));}fnstop(&mutself){ifletSome(tx) = self.tx.as_ref(){let _ = tx.send(Request::Stop);}self.tx.take();ifletSome(iot) = self.iot.take(){
iot.join().unwrap();}}fnnew_sender(&self) -> SyncSender<Request>{self.tx.as_ref().unwrap().clone()}fndelete_sender(_sender:SyncSender<Request>){}}fnsend_job1(sender:&SyncSender<Request>) -> bool{letmut status = false;match sender.send(Request::JOB1()){Ok(_) => status = true,Err(e) => println!("send err: {:?}", e),}
status
}fnsend_job2(sender:&SyncSender<Request>) -> bool{let(tx, rx) = channel();letmut status = false;match sender.send(Request::JOB2(tx)){Ok(()) => match rx.recv(){Ok(_) => status = true,Err(e) => println!("error receiving response {}", e),},Err(e) => println!("send err: {:?}", e),}
status
}
Meta
$ uname -a
Linux mobile 5.14.8-arch1-1 #1 SMP PREEMPT Sun, 26 Sep 2021 19:36:15 +0000 x86_64 GNU/Linux
You're right. Sorry, this is my first experience running sanitizers in Rust. Setting that flag silences the warnings.
With that information I tried the same trick with a nighty closer to the 1.39.0 release and back to my FFI reproducer. Thread sanitzer seg faults, but some println debugging showed the race coming from Sender::recv() which is supposed to block until the request has been processed. Switching to a SyncSender looks like it might be a potential workaround, so I'll give that a shot.
I'm integrating a rust library into a c++ binary (via c FFI) and began noticing some very strange behavior. Compiling the c++ code with thread sanitizer indicates potential data races in the rust standard library. I've created a reproducer that triggers the same tsan backtrace for the version we're using (1.39.0), but it also triggers warnings on nightly when building the rust side with thread sanitizer enabled (see Makefile). The code can be found here and run with
make && ./main
I've further simplified the interaction by reproducing what I believe to be the same issue in safe Rust (below). Also below is the first tsan warning. I see 2 to 4 warnings from the pure rust version depending on the run.
Meta
$ uname -a
Linux mobile 5.14.8-arch1-1 #1 SMP PREEMPT Sun, 26 Sep 2021 19:36:15 +0000 x86_64 GNU/Linux
$ cargo +nightly --version --verbose
cargo 1.57.0-nightly (d56b42c54 2021-09-27)
release: 1.57.0
commit-hash: d56b42c549dbb7e7d0f712c51b39400260d114d4
commit-date: 2021-09-27
first tsan warning...
$ RUSTFLAGS="-Z sanitizer=thread" cargo +nightly run
The text was updated successfully, but these errors were encountered: