Change:
I have code that resembles the following in my application. I'm trying to write a reproduction code, but so far no luck. I expected to see this happen: That it works reliably Instead, this happened: Very rarely I get a segfault, but when I do, gdb always shows the following stack trace <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: I could also see it with
relevant code
cc
does your code contain any ? Waker access is always guarded behind a mutex and the backtrace here actually points to . It seems unlikely that this is a bug in the standard library.
Yes there are a few instances of unsafe, all guarded by debug assertions and such and this is running in debug mode. But I guess it's possible... My understanding is that this happens during drop of after a call to try_select here (which has a inside, which is what eventually segfaults) Which theoretically was put there by a waiting receiver.
Does this problem exist in both std mpsc and crossbeam? Or only in std mpsc? If the latter, the current std mpsc's try_select appears to be based on crossbeam 0.5.2 or 0.5.3 that is affected by compiler or std or OS bug related to TLS access, so changing it may fix the problem.
I left my "repro loop" running for like 1h, and it doesn't seem to fail with crossbeam, only std mpsc (within a minute). Looking at the code I can't tell how the TLS bug would lead to a segfault, but I'm not familiar with the codebase.
WG-prioritization assigning priority (). If I understand, a MCVE would help. am I correct in assuming the codebase is not publicly available? Also, to clarify, you are not reporting a regression, so there's no "good rustc" that doesn't reproduce the issue, correct? label -I-prioritize +P-high +E-needs-mcve
that's correct. I tried, but couldn't successfully write a MCVE. What I was using to "reproduce" was calling the app test suite in a bash loop.

Discussion:
/// Attempts to find another thread's entry, select the operation, and wake it up. #[inline] pub(crate) fn try_select(&mut self) -> Option<Entry> { <del> self.selectors .iter() .position(|selector| { // Does the entry belong to a different thread? selector.cx.thread_id() != current_thread_id() && selector // Try selecting this operation. .cx .try_select(Selected::Operation(selector.oper)) .is_ok() && { // Provide the packet. selector.cx.store_packet(selector.packet); // Wake the thread up. selector.cx.unpark(); true } }) // Remove the entry from the queue to keep it clean and improve // performance. .map(|pos| self.selectors.remove(pos)) </del> <ins> if self.selectors.is_empty() { None } else { let thread_id = current_thread_id(); self.selectors .iter() .position(|selector| { // Does the entry belong to a different thread? selector.cx.thread_id() != thread_id && selector // Try selecting this operation. .cx .try_select(Selected::Operation(selector.oper)) .is_ok() && { // Provide the packet. selector.cx.store_packet(selector.packet); // Wake the thread up. selector.cx.unpark(); true } }) // Remove the entry from the queue to keep it clean and improve // performance. .map(|pos| self.selectors.remove(pos)) } </ins> } /// Notifies all operations waiting to be ready.