Skip to content

Segmentation fault when using spmc:::channel #63256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ZiCog opened this issue Aug 4, 2019 · 11 comments
Closed

Segmentation fault when using spmc:::channel #63256

ZiCog opened this issue Aug 4, 2019 · 11 comments
Labels
C-bug Category: This is a bug. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@ZiCog
Copy link

ZiCog commented Aug 4, 2019

After a few days studying Rust I have come to a road block with segmentation faults and other errors when running a simple program using an mpsc channel.

use std::thread;
use std::fs::File;
use std::io::{BufReader,BufRead};

pub fn main() {
    let (tx, rx) = spmc::channel();

    let mut handles = Vec::new();
    for n in 0..3 {
        let rx = rx.clone();
        handles.push(thread::spawn(move || {
            let mut word_count = 0;
            loop {
                let received = rx.recv();
                match received {
                    Ok(_word) => {
                        word_count = word_count + 1;
                    },
                    Err(_e) => {
                        println!("Reader {}: {}, ", n, word_count);
                        break;
                    }
                }
            }
        }));
    }

    handles.push(thread::spawn(move || {
        let file = File::open("/usr/share/dict/british-english-insane").unwrap();
        for line in BufReader::new(file).lines() {
            let word = line.unwrap();
            tx.send(word).unwrap();
        }
    }));

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Done.");
}

This code should simply read all the lines of a Debian dictionary file and forward them to four threads. The expected result is like:

$ ./target/debug/threads-rust
Reader 2: 221485,
Reader 1: 217272,
Reader 0: 215518,
Done.

But mostly I get seg faults and other errors like so:

$ RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
    Running `target/debug/threads-rust`
munmap_chunk(): invalid pointer
Aborted (core dumped)
$ RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
    Running `target/debug/threads-rust`
Segmentation fault (core dumped)
$ RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.03s
    Running `target/debug/threads-rust`
Reader 0: 654276,
Done.
$ RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.03s
    Running `target/debug/threads-rust`
munmap_chunk(): invalid pointer
Aborted (core dumped)
$ RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.03s
    Running `target/debug/threads-rust`
free(): invalid size
Aborted (core dumped)
$ RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
    Running `target/debug/threads-rust`
double free or corruption (out)
Aborted (core dumped)

I get similar errors on a Raspberry Pi 3.

$ uname -a
Linux monster 4.4.0-17134-Microsoft #706-Microsoft Mon Apr 01 18:13:00 PST 2019 x86_64 GNU/Linux
$ cargo --version
cargo 1.36.0 (c4fcfb725 2019-05-15)
$ rustc --version --verbose
rustc 1.36.0 (a53f9df32 2019-07-03)
binary: rustc
commit-hash: a53f9df32fbb0b5f4382caaad8f1a46f36ea887c
commit-date: 2019-07-03
host: x86_64-unknown-linux-gnu
release: 1.36.0
LLVM version: 8.0    $ cargo  build
Compiling threads-rust v0.1.0 (/mnt/c/Users/zicog/conveqs/threads-rust)
    Finished dev [unoptimized + debuginfo] target(s) in 1.72s
@Mark-Simulacrum
Copy link
Member

cc #39364

Looks like another bug in channels. IIRC, we had loosely discussed that we might want to deprecate std channels at the all hands, but I don't recall specific conclusions. Maybe @alexcrichton remembers better?

@Mark-Simulacrum Mark-Simulacrum added I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Aug 4, 2019
@jonas-schievink jonas-schievink added the C-bug Category: This is a bug. label Aug 4, 2019
@Centril Centril added the I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness label Aug 4, 2019
@RalfJung
Copy link
Member

RalfJung commented Aug 4, 2019

However, even deprecated APIs are covered by our "no UB in safe code" promise.

@jonas-schievink
Copy link
Contributor

@mati865
Copy link
Contributor

mati865 commented Aug 4, 2019

let (tx, rx) = spmc::channel(); it's not std::sync::mpsc::channel but spmc crate.
If you want to report bug in std::sync::mpsc::channel you should modify your example to use it.

@Centril Centril changed the title Segmentation fault when using mpsc:::channel Segmentation fault when using spmc:::channel Aug 4, 2019
@ZiCog
Copy link
Author

ZiCog commented Aug 4, 2019

Sorry for the title confusion. I do actually mean Single Producer Multiple Receiver, spmc, as per my code example.

I do hope a sweet channel solution can be found.

It would be nice to reference Tony Hoare in the channels documentation, given his work on Communicating Sequential Processes.

@Mark-Simulacrum
Copy link
Member

This issue should then be filed against https://github.com/seanmonstar/spmc, as this issue tracker is for Rust itself only. As such, I'm going to close this bug.

@ZiCog
Copy link
Author

ZiCog commented Aug 4, 2019

OK. Understood.

@mati865
Copy link
Contributor

mati865 commented Aug 4, 2019

By the way it looks to me you are using WSL which has many more or less serious bugs.

Right now I only have access to Windows GNU environment but I downloaded https://packages.ubuntu.com/disco/wbritish-insane and ran your example:

$ cargo run --release
    Finished release [optimized] target(s) in 0.01s
     Running `target\release\foo.exe`
Reader 1: 212219,
Reader 2: 224820,
Reader 0: 217176,
Done.

I get similar errors on a Raspberry Pi 3.

If it works in proper x86_64 Linux environment (no compatibility layers or emulators) and doesn't work in armv7 Linux then it's Rust bug.

@RalfJung
Copy link
Member

RalfJung commented Aug 4, 2019

If it works in proper x86_64 Linux environment (no compatibility layers or emulators) and doesn't work in armv7 Linux then it's Rust bug.

That, or the code has UB. We've seen UB-induced ARM-only SIGILLs before, for example.

@ZiCog
Copy link
Author

ZiCog commented Aug 4, 2019

I have built so much software under WSL without issue that it never occurred to me that might be an problem.

But the same issue exists on a real native Debian x86-64 box and on a Pi running 64 bit Debian.

On a real native Debian PC:

zicog@jhctech1:~/threads-rust$ uname -a
Linux jhctech1 4.19.0-5-amd64 #1 SMP Debian 4.19.37-5 (2019-06-19) x86_64 GNU/Linux
zicog@jhctech1:~/threads-rust$ rustc --version --verbose
rustc 1.36.0 (a53f9df32 2019-07-03)
binary: rustc
commit-hash: a53f9df32fbb0b5f4382caaad8f1a46f36ea887c
commit-date: 2019-07-03
host: x86_64-unknown-linux-gnu
release: 1.36.0
LLVM version: 8.0
zicog@jhctech1:~/threads-rust$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
    Running `target/debug/threads-rust`
double free or corruption (out)
Aborted

On a Raspberry Pi running 64 bit Debian:

$ rustc --verbose --version
rustc 1.36.0 (a53f9df32 2019-07-03)
binary: rustc
commit-hash: a53f9df32fbb0b5f4382caaad8f1a46f36ea887c
commit-date: 2019-07-03
host: aarch64-unknown-linux-gnu
release: 1.36.0
LLVM version: 8.0
$ uname -a
Linux pi64-aalto 4.11.12-pi64+ #1 SMP PREEMPT Sun Jul 30 20:18:20 CEST 2017 aarch64 GNU/Linux
pi@pi64-aalto:~/threads-rust$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
    Running `target/debug/threads-rust`
*** Error in `target/debug/threads-rust': malloc(): memory corruption (fast): 0x0000007fa00029e0 ***
Aborted

I would try it under Windows in the DOS box but that requires installing Visual Studio which is not going to happen here.

Being a Rust newbie I have no idea what goes on in the spmc source but I see it has a lot of "unsafe".

I have reported the issue on the spmc github repo.

Thanks everybody.

@mati865
Copy link
Contributor

mati865 commented Aug 4, 2019

double free or corruption

It means glibc detected bug in the software, Windows isn't that good in that regard.

I would try it under Windows in the DOS box but that requires installing Visual Studio which is not going to happen here.

Windows MSVC requires additional steps but Windows GNU toolchain may work without out of the box. But since glibc error is legit there is no need to test it on Windows.

I have built so much software under WSL without issue that it never occurred to me that might be an problem.

Rust example: #60475
There are also issues with Python programs and Redis among the others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants