Closed
Description
I tried this code:
use std::sync::mpsc::*;
struct BigStruct {
_data: [u32; 32000],
}
fn main() {
let thread = std::thread::spawn(move || {
let (_sender, receiver) = channel::<BigStruct>();
for _data in receiver.try_iter() {
}
});
thread.join().unwrap();
println!("Done :)");
}
I expected to see this happen:
The program shouldn't do much beside printing a friendly message.
Instead, this happened:
When running in Debug mode, the program crashes due to a stack overflow. In release mode it behaves as expected. Looping over the data in the receiver in combination with being on a separate thread triggers it.
I tried running on nightly too, which produces the same results.
I've now switched to crossbeam as a workaround, which does not suffer from the same issue fortunately.
rustc --version --verbose
:
rustc 1.64.0 (a55dd71d5 2022-09-19)
binary: rustc
commit-hash: a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52
commit-date: 2022-09-19
host: x86_64-pc-windows-msvc
release: 1.64.0
LLVM version: 14.0.6
Backtrace
thread '<unknown>' has overflowed its stack
Activity
lapointexavier commentedon Aug 1, 2023
I've run into this when upgrading from
1.70.0
to1.71.0
. Compiling in release mode prevented the segfault when using1.71.0
, though the issue was not happening in1.70.0
.ChrisDenton commentedon Aug 11, 2023
I've not been able to reproduce this using the program in the OP. I've tried on both
1.71.1
and1.73.0-nightly
. In both cases it prints "Done :)".lapointexavier commentedon Aug 11, 2023
@ChrisDenton OP's didn't trigger it for me either, but after playing with it I was able to reproduce:
Repro
Output
lapointexavier commentedon Aug 11, 2023
Also this may be system dependent, but I was playing with slice sizes and the trigger seems to be
8120 + 1
for the overflow. I don't know why release mode doesn't overflow, maybe something is being optimized.ChrisDenton commentedon Aug 12, 2023
Ok, I've not yet investigated but my guess would be something about how it's not being optimized in
start_send
is multiplying the needed stack space by a fair amount.@ibraheemdev might have some ideas. Note though this only affects
opt-level=0
builds.Enselic commentedon Nov 5, 2024
The reproduer can be simplifed to:
Regressed versions
The code runs fine in debug builds with 1.66 but not with 1.67. So this is a regression-from-stable-to-stable, but arguably not very severe since this seemingly has gone mostly unnoticed for a considerable amount of time.
With
cargo bisect-rustc
we find that this runs fine with nightly-2022-11-13 but not nightly-2022-11-14 which leaves us withof which #93563 seems most likely.
To demonstrate:
Disassembly
The disassembly of
std::sync::mpmc::list::Channel<[u8; 32768]>::start_send<[u8; 32768]>
where we SIGSEGV in gdb looks like this:So we SIGSEGV when
0
is being written to the top of the stack (probably due to stack probing) after growing it ~0x1f0000 bytes which is ~2MB.In the LLVM IR we can find:
I looked at the MIR too but couldn't find anything suspicious. Maybe someone used to debuggging monomorphization/codegen can easily find out why the stack grows by 2MB.
My system
17 remaining items