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

Segmentation fault when transmuting simd vector temporary #32947

Closed
ruuda opened this issue Apr 14, 2016 · 6 comments · Fixed by #38670
Closed

Segmentation fault when transmuting simd vector temporary #32947

ruuda opened this issue Apr 14, 2016 · 6 comments · Fixed by #38670
Assignees
Labels
T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@ruuda
Copy link
Contributor

ruuda commented Apr 14, 2016

This is a pretty subtle interaction of several things that produces code which causes a segmentation fault:

  • A struct with #[repr(simd)].
  • A struct with a member.
  • A method on that struct.
  • Transmuting the result of a method call.
#![feature(repr_simd)]

#[repr(simd)] // Without #[repr(simd)], it works fine.
pub struct Mu64(pub u64, pub u64, pub u64, pub u64);

pub struct Trouble {
    state: Mu64, // Without this field, it works fine.
}

impl Trouble {
    pub fn new() -> Trouble {
        Trouble {
            state: Mu64(1, 2, 3, 4),
        }
    }

    fn next(&self) -> Mu64 {
        Mu64(1, 2, 3, 4)
    }

    pub fn invoke_doom(&self) -> [u32; 8] {
        use std::mem::transmute;
        // transmute(Mu64(1, 2, 3, 4)) instead of transmute(self.next()) works
        // fine.
        unsafe { transmute(self.next()) }
    }
}

#[test]
fn this_causes_sigsegv() {
    let mut trouble = Trouble::new();
    println!("{}", trouble.invoke_doom()[0]);
}

Now cargo test crashes with a segmentation fault. (The test program that is, not Cargo.) cargo test --release runs fine. It could be that this is working as intended, and this is what I get for using unsafe code, but it certainly surprises me.

Workaround for now: use transmute_copy instead of transmute.

Version: rustc 1.9.0-nightly (a43eb4e 2016-04-12). It also happened on an older nightly.

@sanmai-NL
Copy link

sanmai-NL commented Apr 23, 2016

Maybe you can write a PR with a test case so that this gets addressed?

@ruuda
Copy link
Contributor Author

ruuda commented Apr 25, 2016

Tests are usually added after the fix to prevent regressing, but I wouldn’t know where to start in order to fix this.

@dotdash
Copy link
Contributor

dotdash commented Apr 25, 2016

LLVM generates a movaps instruction which assumes that the value aligned on a 16 byte boundary. This happens because we're calling the memcpy intrinsic specifying a 32 byte alignment. But, the stack slot gets no alignment set, so it gets the default 8 byte alignment and we end up with a misaligned read.

@dotdash
Copy link
Contributor

dotdash commented Apr 25, 2016

D'oh, nevermind that. I was looking at the wrong function in the IR. It's actually just transmute that just casts a [8 x i32]* to <4 x i64>* although the former isn't aligned enough.

@dotdash dotdash self-assigned this Apr 25, 2016
dotdash added a commit to dotdash/rust that referenced this issue Apr 27, 2016
For types that are not bitcast-compatible, transmute tries to avoid
generating a temporary by translating its source expression directly
into its destination, but when the source type has a bigger alignment
requirement than the destination, this can lead to code that breaks due
to misaligned stores. So in that case we need to generate a temporary
for the source expression and then copy that into the destination,
setting the proper alignment information on the memcpy/store.

Fixes rust-lang#32947
@bltavares
Copy link
Contributor

Triage: this fails on nightly.

rustc 1.11.0-nightly (6e00b5556 2016-05-29)
cargo 0.11.0-nightly (3ff108a 2016-05-24)

Running cargo test emit some warnings, and fail with segmentation fault:

rustup run nightly cargo test
   Compiling 32947 v0.1.0 (file:///private/tmp/32947)
src/lib.rs:7:5: 7:16 warning: struct field is never used: `state`, #[warn(dead_code)] on by default
src/lib.rs:7     state: Mu64, // Without this field, it works fine.
                 ^~~~~~~~~~~
src/lib.rs:7:5: 7:16 warning: struct field is never used: `state`, #[warn(dead_code)] on by default
src/lib.rs:7     state: Mu64, // Without this field, it works fine.
                 ^~~~~~~~~~~
src/lib.rs:31:9: 31:20 warning: variable does not need to be mutable, #[warn(unused_mut)] on by default
src/lib.rs:31     let mut trouble = Trouble::new();
                      ^~~~~~~~~~~
     Running target/debug/32947-044b564592bca0e2

running 1 test
error: Process didn't exit successfully: `/private/tmp/32947/target/debug/32947-044b564592bca0e2` (signal: 11, SIGSEGV: invalid memory reference)

cargo test --release compiles fine:

rustup run nightly cargo test --release
   Compiling 32947 v0.1.0 (file:///private/tmp/32947)
src/lib.rs:7:5: 7:16 warning: struct field is never used: `state`, #[warn(dead_code)] on by default
src/lib.rs:7     state: Mu64, // Without this field, it works fine.
                 ^~~~~~~~~~~
src/lib.rs:7:5: 7:16 warning: struct field is never used: `state`, #[warn(dead_code)] on by default
src/lib.rs:7     state: Mu64, // Without this field, it works fine.
                 ^~~~~~~~~~~
src/lib.rs:31:9: 31:20 warning: variable does not need to be mutable, #[warn(unused_mut)] on by default
src/lib.rs:31     let mut trouble = Trouble::new();
                      ^~~~~~~~~~~
     Running target/release/32947-044b564592bca0e2

running 1 test
test this_causes_sigsegv ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests 32947

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

@cyplo
Copy link
Contributor

cyplo commented Nov 1, 2016

Still failing on the newest nightly 1.14.0-nightly (f094206 2016-10-20)

dotdash added a commit to dotdash/rust that referenced this issue Dec 31, 2016
For transmute::<T, U> we simply pointercast the destination from a U
pointer to a T pointer, without providing any alignment information,
thus LLVM assumes that the destination is aligned to hold a value of
type T, which is not necessarily true. This can lead to LLVM emitting
machine instructions that assume said alignment, and thus cause aborts.

To fix this, we need to provide the actual alignment to store_operand()
and in turn to store() so they can set the proper alignment information
on the stores and LLVM can emit the proper machine instructions.

Fixes rust-lang#32947
bors added a commit that referenced this issue Jan 4, 2017
Fix transmute::<T, U> where T requires a bigger alignment than U

For transmute::<T, U> we simply pointercast the destination from a U
pointer to a T pointer, without providing any alignment information,
thus LLVM assumes that the destination is aligned to hold a value of
type T, which is not necessarily true. This can lead to LLVM emitting
machine instructions that assume said alignment, and thus cause aborts.

To fix this, we need to provide the actual alignment to store_operand()
and in turn to store() so they can set the proper alignment information
on the stores and LLVM can emit the proper machine instructions.

Fixes #32947
@steveklabnik steveklabnik added T-lang Relevant to the language team, which will review and decide on the PR/issue. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 24, 2017
JohnTitor added a commit to JohnTitor/rust that referenced this issue Feb 1, 2021
…chenkov

Move some tests to more reasonable directories - 3

cc rust-lang#73494
r? `@petrochenkov`

https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-56202.rs <sup>https://github.com/rust-lang/rust/issues/56202</sup>: traits 1.008
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-69841.rs <sup>https://github.com/rust-lang/rust/issues/69841</sup>: for-loop-while 1.014
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-10763.rs <sup>https://github.com/rust-lang/rust/issues/10763</sup>: extern 1.016
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-50599.rs <sup>https://github.com/rust-lang/rust/issues/50599</sup>: resolve 1.018
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-6128.rs <sup>https://github.com/rust-lang/rust/issues/6128</sup>: traits 1.043
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-20616-8.rs <sup>https://github.com/rust-lang/rust/issues/20616</sup>: parser 1.045
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-46553.rs <sup>https://github.com/rust-lang/rust/issues/46553</sup>: consts 1.081
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-33140-hack-boundaries.rs <sup>https://github.com/rust-lang/rust/issues/33140</sup>: traits 1.101
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-25826.rs <sup>https://github.com/rust-lang/rust/issues/25826</sup>: consts 1.108
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-56488.rs <sup>https://github.com/rust-lang/rust/issues/56488</sup>: traits 1.110
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-58856-1.rs <sup>https://github.com/rust-lang/rust/issues/58856</sup>: parser 1.133
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-57819.rs <sup>https://github.com/rust-lang/rust/issues/57819</sup>: parser 1.138
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-54348.rs <sup>https://github.com/rust-lang/rust/issues/54348</sup>: consts 1.155
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-14309.rs <sup>https://github.com/rust-lang/rust/issues/14309</sup>: lint 1.160
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-4446.rs <sup>https://github.com/rust-lang/rust/issues/4446</sup>: threads-sendsync 1.203
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-53675-a-test-called-panic.rs <sup>https://github.com/rust-lang/rust/issues/53675</sup>: test-attrs 1.211
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-40231-2.rs <sup>https://github.com/rust-lang/rust/issues/40231</sup>: consts 1.213
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-22037.rs <sup>https://github.com/rust-lang/rust/issues/22037</sup>: associated-types 1.214
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-59029-2.rs <sup>https://github.com/rust-lang/rust/issues/59029</sup>: traits 1.219
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-18425.rs <sup>https://github.com/rust-lang/rust/issues/18425</sup>: consts 1.237
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-6157.rs <sup>https://github.com/rust-lang/rust/issues/6157</sup>: regions 1.238
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-33819.rs <sup>https://github.com/rust-lang/rust/issues/33819</sup>: borrowck 1.280
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-3683.rs <sup>https://github.com/rust-lang/rust/issues/3683</sup>: traits 1.283
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-8709.rs <sup>https://github.com/rust-lang/rust/issues/8709</sup>: macros 1.291
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-20616-9.rs <sup>https://github.com/rust-lang/rust/issues/20616</sup>: parser 1.293
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-64732.rs <sup>https://github.com/rust-lang/rust/issues/64732</sup>: parser 1.296
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-18655.rs <sup>https://github.com/rust-lang/rust/issues/18655</sup>: associated-types 1.305
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-32947.rs <sup>https://github.com/rust-lang/rust/issues/32947</sup>: simd 1.322
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-57198.rs <sup>https://github.com/rust-lang/rust/issues/57198</sup>: parser 1.342
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-10764-rpass.rs <sup>https://github.com/rust-lang/rust/issues/10764</sup>: extern 1.392
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-73541-2.rs <sup>https://github.com/rust-lang/rust/issues/73541</sup>: async-await 1.422
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-7970b.rs <sup>https://github.com/rust-lang/rust/issues/7970</sup>: parser 1.439
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-57684.rs <sup>https://github.com/rust-lang/rust/issues/57684</sup>: parser 1.512
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-33264.rs <sup>https://github.com/rust-lang/rust/issues/33264</sup>: llvm-asm 1.523
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-65284-suggest-generic-trait-bound.rs <sup>https://github.com/rust-lang/rust/issues/65284</sup>: suggestions 1.647
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-17458.rs <sup>https://github.com/rust-lang/rust/issues/17458</sup>: consts 1.711
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-56762.rs <sup>https://github.com/rust-lang/rust/issues/56762</sup>: consts 1.787
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-2216.rs <sup>https://github.com/rust-lang/rust/issues/2216</sup>: for-loop-while 1.856
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.rs <sup>https://github.com/rust-lang/rust/issues/45696</sup>: nll 2.009
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-46036.rs <sup>https://github.com/rust-lang/rust/issues/46036</sup>: nll 2.059

`@petrochenkov` Can you put a place holder (like `N/A`) for tests without GitHub issues? It is a lot easier to parse fixed sized rows.
henryboisdequin pushed a commit to henryboisdequin/rust that referenced this issue Feb 1, 2021
…chenkov

Move some tests to more reasonable directories - 3

cc rust-lang#73494
r? ``@petrochenkov``

https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-56202.rs <sup>https://github.com/rust-lang/rust/issues/56202</sup>: traits 1.008
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-69841.rs <sup>https://github.com/rust-lang/rust/issues/69841</sup>: for-loop-while 1.014
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-10763.rs <sup>https://github.com/rust-lang/rust/issues/10763</sup>: extern 1.016
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-50599.rs <sup>https://github.com/rust-lang/rust/issues/50599</sup>: resolve 1.018
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-6128.rs <sup>https://github.com/rust-lang/rust/issues/6128</sup>: traits 1.043
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-20616-8.rs <sup>https://github.com/rust-lang/rust/issues/20616</sup>: parser 1.045
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-46553.rs <sup>https://github.com/rust-lang/rust/issues/46553</sup>: consts 1.081
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-33140-hack-boundaries.rs <sup>https://github.com/rust-lang/rust/issues/33140</sup>: traits 1.101
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-25826.rs <sup>https://github.com/rust-lang/rust/issues/25826</sup>: consts 1.108
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-56488.rs <sup>https://github.com/rust-lang/rust/issues/56488</sup>: traits 1.110
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-58856-1.rs <sup>https://github.com/rust-lang/rust/issues/58856</sup>: parser 1.133
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-57819.rs <sup>https://github.com/rust-lang/rust/issues/57819</sup>: parser 1.138
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-54348.rs <sup>https://github.com/rust-lang/rust/issues/54348</sup>: consts 1.155
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-14309.rs <sup>https://github.com/rust-lang/rust/issues/14309</sup>: lint 1.160
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-4446.rs <sup>https://github.com/rust-lang/rust/issues/4446</sup>: threads-sendsync 1.203
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-53675-a-test-called-panic.rs <sup>https://github.com/rust-lang/rust/issues/53675</sup>: test-attrs 1.211
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-40231-2.rs <sup>https://github.com/rust-lang/rust/issues/40231</sup>: consts 1.213
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-22037.rs <sup>https://github.com/rust-lang/rust/issues/22037</sup>: associated-types 1.214
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-59029-2.rs <sup>https://github.com/rust-lang/rust/issues/59029</sup>: traits 1.219
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-18425.rs <sup>https://github.com/rust-lang/rust/issues/18425</sup>: consts 1.237
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-6157.rs <sup>https://github.com/rust-lang/rust/issues/6157</sup>: regions 1.238
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-33819.rs <sup>https://github.com/rust-lang/rust/issues/33819</sup>: borrowck 1.280
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-3683.rs <sup>https://github.com/rust-lang/rust/issues/3683</sup>: traits 1.283
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-8709.rs <sup>https://github.com/rust-lang/rust/issues/8709</sup>: macros 1.291
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-20616-9.rs <sup>https://github.com/rust-lang/rust/issues/20616</sup>: parser 1.293
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-64732.rs <sup>https://github.com/rust-lang/rust/issues/64732</sup>: parser 1.296
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-18655.rs <sup>https://github.com/rust-lang/rust/issues/18655</sup>: associated-types 1.305
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-32947.rs <sup>https://github.com/rust-lang/rust/issues/32947</sup>: simd 1.322
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-57198.rs <sup>https://github.com/rust-lang/rust/issues/57198</sup>: parser 1.342
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-10764-rpass.rs <sup>https://github.com/rust-lang/rust/issues/10764</sup>: extern 1.392
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-73541-2.rs <sup>https://github.com/rust-lang/rust/issues/73541</sup>: async-await 1.422
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-7970b.rs <sup>https://github.com/rust-lang/rust/issues/7970</sup>: parser 1.439
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-57684.rs <sup>https://github.com/rust-lang/rust/issues/57684</sup>: parser 1.512
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-33264.rs <sup>https://github.com/rust-lang/rust/issues/33264</sup>: llvm-asm 1.523
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-65284-suggest-generic-trait-bound.rs <sup>https://github.com/rust-lang/rust/issues/65284</sup>: suggestions 1.647
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-17458.rs <sup>https://github.com/rust-lang/rust/issues/17458</sup>: consts 1.711
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-56762.rs <sup>https://github.com/rust-lang/rust/issues/56762</sup>: consts 1.787
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-2216.rs <sup>https://github.com/rust-lang/rust/issues/2216</sup>: for-loop-while 1.856
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.rs <sup>https://github.com/rust-lang/rust/issues/45696</sup>: nll 2.009
https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-46036.rs <sup>https://github.com/rust-lang/rust/issues/46036</sup>: nll 2.059

``@petrochenkov`` Can you put a place holder (like `N/A`) for tests without GitHub issues? It is a lot easier to parse fixed sized rows.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants