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

Comments

Projects
None yet
9 participants
@pythonesque
Copy link
Contributor

pythonesque commented Jun 12, 2015

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

This comment has been minimized.

Copy link
Member

sfackler commented Jun 12, 2015

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

@sfackler sfackler added the O-macos label Jun 12, 2015

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Jun 12, 2015

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

This comment has been minimized.

Copy link
Contributor Author

pythonesque commented Jun 12, 2015

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

This comment has been minimized.

Copy link
Contributor Author

pythonesque commented Jun 13, 2015

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).

@crharris

This comment has been minimized.

Copy link

crharris commented Aug 20, 2015

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

This comment has been minimized.

Copy link
Member

steveklabnik commented Nov 5, 2015

Tagging as unsound due to segfault in stable rust.

@bstrie bstrie added the I-nominated label Nov 30, 2015

@bstrie

This comment has been minimized.

Copy link
Contributor

bstrie commented Nov 30, 2015

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

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Dec 17, 2015

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 and removed I-nominated labels Dec 17, 2015

@dotdash

This comment has been minimized.

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

This comment has been minimized.

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

Fix emitting asm and object file output at the same time
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

dotdash added a commit to dotdash/rust that referenced this issue Dec 18, 2015

Fix emitting asm and object file output at the same time
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

dotdash added a commit to dotdash/rust that referenced this issue Dec 18, 2015

Fix emitting asm and object file output at the same time
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

Rollup merge of rust-lang#30452 - dotdash:24876_take_2, r=alexcrichton
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

Rollup merge of rust-lang#30452 - dotdash:24876_take_2, r=alexcrichton
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

Rollup merge of rust-lang#30452 - dotdash:24876_take_2, r=alexcrichton
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

Rollup merge of rust-lang#30452 - dotdash:24876_take_2, r=alexcrichton
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

@bors bors closed this in #30452 Dec 18, 2015

fhahn added a commit to fhahn/rust that referenced this issue Dec 28, 2015

Fix emitting asm and object file output at the same time
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
You can’t perform that action at this time.