Skip to content
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

Segfault in safe code on Rust nightly when running rustc --emit=asm,link #26235

Closed
pythonesque opened this issue Jun 12, 2015 · 10 comments
Closed
Labels
I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness O-macos Operating system: macOS P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@pythonesque
Copy link
Contributor

This reliably segfaults for me on a 13 inch 2015 Macbook Air running OS X Yosemite. I'm not sure what the culprit is yet; it might be trans. I haven't tested it with stable yet.

fn main() {
    use std::thread;

    type Key = u32;
    const NUM_THREADS: usize = 2;

    #[derive(Clone,Copy)] struct Stats<S> { upsert: S, delete: S, insert: S, update: S };
    impl<S> Stats<S> where S: Copy {
        fn dot<B, F, T>(self, s: Stats<T>, f: F) -> Stats<B> where F: Fn(S, T) -> B {
            let Stats { upsert: u1, delete: d1, insert: i1, update: p1 } = self;
            let Stats { upsert: u2, delete: d2, insert: i2, update: p2 } = s;
            Stats { upsert: f(u1, u2), delete: f(d1, d2), insert: f(i1, i2), update: f(p1, p2) }
        }
        fn new(init: S) -> Self {
            Stats { upsert: init, delete: init, insert: init, update: init }
        }
    }
    fn make_threads() -> Vec<thread::JoinHandle<()>> {
        let mut t = Vec::with_capacity(NUM_THREADS);
        for _ in 0..NUM_THREADS {
            t.push(thread::spawn(move || {}));
        }
        t
    }
    let stats = [Stats::new(0) ; NUM_THREADS];
    make_threads();
    {
        let Stats { ref upsert, ref delete, ref insert, ref update } =
            stats.iter().fold(Stats::new(0), |res, &s| res.dot(s, |x: Key, y: Key| x.wrapping_add(y) ) );
        println!("upserts: {}, deletes: {}, inserts: {}, updates: {}",
                 upsert, delete, insert, update);
    }
}

$ rustc foo.rs -C opt-level=3 --emit=asm,link
$ ./foo
Illegal instruction: 4 # or Segmentation fault: 11

Maybe related to #24876 ?

@sfackler
Copy link
Member

Seems to run fine on both 1.0 stable and a nightly on x86_64 Linux.

@sfackler sfackler added the O-macos Operating system: macOS label Jun 12, 2015
@alexcrichton
Copy link
Member

Confirmed to segfault on OSX with stable rust. Also confirmed to have different IR with --emit asm or not, although only in symbol names... not entirely sure what's going on here.

@pythonesque
Copy link
Contributor Author

Finding it hard to reduce further than this testcase (the usual tricks for getting rid of stuff like Vec don't appear to be working):

fn main() {
    use std::thread;
    let ref foo = [(0, 0, 0, 0)];
    vec![thread::Builder::new().spawn(|| ()).ok()];
    {
        let mut res = (0, 0, 0, 0);
        for s in foo {
            res = (s.0, s.1, s.2, s.3);
        }
        println!("{}{}", res.0, res.1);
    }
}

@pythonesque
Copy link
Contributor Author

Interestingly, in a dummy implementation which includes thread::Builder, removing the mutex used for park / unpark seems to make the issue go away (no idea if that's the real problem though).

@chrisrharris
Copy link

I also ran into a segfault with cargo on rust 1.2, but only when installing rust from homebrew. (OSX Yosemite 10.10.4)

@steveklabnik steveklabnik added the I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness label Nov 5, 2015
@steveklabnik
Copy link
Member

Tagging as unsound due to segfault in stable rust.

@bstrie
Copy link
Contributor

bstrie commented Nov 30, 2015

Nominating as this is a soundness bug that has yet to have a priority assigned.

@alexcrichton alexcrichton added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Dec 16, 2015
@nikomatsakis
Copy link
Contributor

triage: P-medium

Believed to be specific to --emit asm,link, which is a rather specific scenario. We believe the fix is #29385.

@rust-highfive rust-highfive added P-medium Medium priority and removed I-nominated labels Dec 17, 2015
@dotdash
Copy link
Contributor

dotdash commented Dec 17, 2015

@alexcrichton you're seeing the same asm from --emit=asm because that happens first, because the codegen for the link output breaks things. You do get different asm if you look at the output from objdump -S (I don't know what's the equivalent tool on OSX)

@dotdash
Copy link
Contributor

dotdash commented Dec 17, 2015

... that's using --emit=link vs. --emit=asm,link then, of course.

dotdash added a commit to dotdash/rust that referenced this issue Dec 18, 2015
LLVM doesn't really support reusing the same module to emit more than
one file. One bug this causes is that the IR is invalidated by the stack
coloring pass when emitting the first file, and then the IR verifier
complains by the time we try to emit the second file. Also, we get
different binaries with --emit=asm,link than with just --emit=link. In
some cases leading to segfaults.

Unfortunately, it seems that at this point in time, the most sensible
option to circumvent this problem is to just clone the whole llvm module
for the asm output if we need both, asm and obj file output.

Fixes rust-lang#24876
Fixes rust-lang#26235
Manishearth added a commit to Manishearth/rust that referenced this issue Dec 18, 2015
LLVM doesn't really support reusing the same module to emit more than
one file. One bug this causes is that the IR is invalidated by the stack
coloring pass when emitting the first file, and then the IR verifier
complains by the time we try to emit the second file. Also, we get
different binaries with --emit=asm,link than with just --emit=link. In
some cases leading to segfaults.

Unfortunately, it seems that at this point in time, the most sensible
option to circumvent this problem is to just clone the whole llvm module
for the asm output if we need both, asm and obj file output.

Fixes rust-lang#24876
Fixes rust-lang#26235
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness O-macos Operating system: macOS P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

9 participants