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

Assertion failure only when compiling with -O #2989

Closed
Dretch opened this issue Jul 22, 2012 · 4 comments
Closed

Assertion failure only when compiling with -O #2989

Dretch opened this issue Jul 22, 2012 · 4 comments
Labels
A-codegen Area: Code generation
Milestone

Comments

@Dretch
Copy link
Contributor

Dretch commented Jul 22, 2012

The assert in this crate (which is derived from std::bitv) passes when compiled without -O and fails when compiled with -O:

use std;

fn some_unused_fn() { fail }

trait methods {
    fn to_bytes() -> ~[u8];
}

impl of methods for () {
    fn to_bytes() -> ~[u8] {
        vec::from_elem(42, 0)
    }
}

// the position of this function is significant! - if it comes before methods
// then it works, if it comes after it then it doesnt!
fn to_bools(bitv: {storage: ~[u64], nbits: uint}) -> ~[bool] {
    vec::from_fn(bitv.nbits, |i| {
        let w = i / 64;
        let b = i % 64;
        let x = 1u64 & (bitv.storage[w] >> b);
        x == 1u64
    })
}

fn main() {
    let bools = ~[false, false, true, false, false, true, true, false];
    let bitv  = {storage: ~[0b01100100], nbits: 8};
    assert to_bools(bitv) == bools;
}

As mentioned in a comment in the code the position of the items in the crate also seem to be significant. Removing some_unused_fn and/or methods also makes the code work as expected.

This bug is blocking #2964 and possibly #2341.

I found this bug on a 64 bit Ubuntu system.

@Dretch
Copy link
Contributor Author

Dretch commented Jul 22, 2012

I have now done a little more investigation.

Using the following code, which is a simplified version of the original that also has some io::println added for debugging:

use std;

trait methods {
    fn to_bytes() -> ~[u8];
}

impl of methods for () {
    fn to_bytes() -> ~[u8] {
        vec::from_elem(0, 0)
    }
}

// the position of this function is significant! - if it comes before methods
// then it works, if it comes after it then it doesnt!
fn to_bools(bitv: {storage: ~[u64]}) -> ~[bool] {
    vec::from_fn(8, |i| {
        let w = i / 64;
        let b = i % 64;
        let x = 1u64 & (bitv.storage[w] >> b);
        x == 1u64
    })
}

fn main() {
    let bools = ~[false, false, true, false, false, true, true, false];
    let bools2 = to_bools({storage: ~[0b01100100]});

    for uint::range(0, 8) |i| {
        io::println(#fmt("%u => %u vs %u", i, bools[i] as uint, bools2[i] as uint));
    }

    assert bools == bools2;
}

Compilation without -O produces the expected output:

gareth@dimension:~/projects/tests$ rustc bitv2-test.rs && ./bitv2-test 
0 => 0 vs 0
1 => 0 vs 0
2 => 1 vs 1
3 => 0 vs 0
4 => 0 vs 0
5 => 1 vs 1
6 => 1 vs 1
7 => 0 vs 0

And compilation with -O produces some strange output and an assertion failure:

gareth@dimension:~/projects/tests$ rustc -O bitv2-test.rs && ./bitv2-test 
0 => 0 vs 192
1 => 0 vs 192
2 => 1 vs 193
3 => 0 vs 192
4 => 0 vs 192
5 => 1 vs 193
6 => 1 vs 193
7 => 0 vs 192
rust: task failed at 'Assertion bools == bools2 failed', bitv2-test.rs:33
rust: domain main @0x183ab80 root task failed

Its like the optimized code is producing bools that are off by 192.

@Dretch
Copy link
Contributor Author

Dretch commented Jul 27, 2012

Just in case this might be useful... when this code was inside std::bitv then the test suite failed valgrind with a bunch of stuff like:

==24424== Invalid write of size 8
==24424==    at 0x554F76F: ev_run (ev.c:2198)
==24424==    by 0x5541EB1: uv_run (core.c:212)
==24424==    by 0x554100C: ??? (in /home/gareth/projects/dretch-rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so)
==24424==  Address 0x6ddfb68 is 2,744 bytes inside a block of size 3,632 free'd
==24424==    at 0x4C282E0: free (vg_replace_malloc.c:366)
==24424==    by 0x552D3E6: rust_task::cleanup_after_turn() (rust_task.cpp:561)
==24424==    by 0x5529ED4: rust_sched_loop::activate(rust_task*) (rust_sched_loop.cpp:47)
==24424==    by 0x552A020: rust_sched_loop::run_single_turn() (rust_sched_loop.cpp:230)
==24424==    by 0x552B704: rust_sched_driver::start_main_loop() (rust_sched_driver.cpp:28)
==24424==    by 0x5524BB9: rust_thread_start(void*) (rust_thread.cpp:25)
==24424==    by 0x63BFEFB: start_thread (pthread_create.c:304)
==24424==    by 0x5A6A59C: clone (clone.S:112)
==24424== 
==24424== Invalid write of size 4
==24424==    at 0x554F701: ev_run (ev.c:1189)
==24424==    by 0x5541EB1: uv_run (core.c:212)
==24424==    by 0x554100C: ??? (in /home/gareth/projects/dretch-rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so)
==24424==  Address 0x6ddfb48 is 2,712 bytes inside a block of size 3,632 free'd
==24424==    at 0x4C282E0: free (vg_replace_malloc.c:366)
==24424==    by 0x552D3E6: rust_task::cleanup_after_turn() (rust_task.cpp:561)
==24424==    by 0x5529ED4: rust_sched_loop::activate(rust_task*) (rust_sched_loop.cpp:47)
==24424==    by 0x552A020: rust_sched_loop::run_single_turn() (rust_sched_loop.cpp:230)
==24424==    by 0x552B704: rust_sched_driver::start_main_loop() (rust_sched_driver.cpp:28)
==24424==    by 0x5524BB9: rust_thread_start(void*) (rust_thread.cpp:25)
==24424==    by 0x63BFEFB: start_thread (pthread_create.c:304)
==24424==    by 0x5A6A59C: clone (clone.S:112)
==24424== 
==24424== Invalid read of size 4
==24424==    at 0x554BB93: ev_feed_event (ev.c:900)
==24424==    by 0x554F851: ev_run (ev.c:924)
==24424==    by 0x5541EB1: uv_run (core.c:212)
==24424==    by 0x554100C: ??? (in /home/gareth/projects/dretch-rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so)
==24424==  Address 0x6ddfb50 is 2,720 bytes inside a block of size 3,632 free'd
==24424==    at 0x4C282E0: free (vg_replace_malloc.c:366)
==24424==    by 0x552D3E6: rust_task::cleanup_after_turn() (rust_task.cpp:561)
==24424==    by 0x5529ED4: rust_sched_loop::activate(rust_task*) (rust_sched_loop.cpp:47)
==24424==    by 0x552A020: rust_sched_loop::run_single_turn() (rust_sched_loop.cpp:230)
==24424==    by 0x552B704: rust_sched_driver::start_main_loop() (rust_sched_driver.cpp:28)
==24424==    by 0x5524BB9: rust_thread_start(void*) (rust_thread.cpp:25)
==24424==    by 0x63BFEFB: start_thread (pthread_create.c:304)
==24424==    by 0x5A6A59C: clone (clone.S:112)
==24424== 
==24424== Invalid read of size 4
==24424==    at 0x554BB97: ev_feed_event (ev.c:902)
==24424==    by 0x554F851: ev_run (ev.c:924)
==24424==    by 0x5541EB1: uv_run (core.c:212)
==24424==    by 0x554100C: ??? (in /home/gareth/projects/dretch-rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so)
==24424==  Address 0x6ddfb4c is 2,716 bytes inside a block of size 3,632 free'd
==24424==    at 0x4C282E0: free (vg_replace_malloc.c:366)
==24424==    by 0x552D3E6: rust_task::cleanup_after_turn() (rust_task.cpp:561)
==24424==    by 0x5529ED4: rust_sched_loop::activate(rust_task*) (rust_sched_loop.cpp:47)
==24424==    by 0x552A020: rust_sched_loop::run_single_turn() (rust_sched_loop.cpp:230)
==24424==    by 0x552B704: rust_sched_driver::start_main_loop() (rust_sched_driver.cpp:28)
==24424==    by 0x5524BB9: rust_thread_start(void*) (rust_thread.cpp:25)
==24424==    by 0x63BFEFB: start_thread (pthread_create.c:304)
==24424==    by 0x5A6A59C: clone (clone.S:112)
==24424== 
==24424== Invalid read of size 4
==24424==    at 0x554BBAD: ev_feed_event (ev.c:906)
==24424==    by 0x554F851: ev_run (ev.c:924)
==24424==    by 0x5541EB1: uv_run (core.c:212)
==24424==    by 0x554100C: ??? (in /home/gareth/projects/dretch-rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so)
==24424==  Address 0x227ab8bc is not stack'd, malloc'd or (recently) free'd
==24424== 
==24424== 
==24424== Process terminating with default action of signal 11 (SIGSEGV)
==24424==  Access not within mapped region at address 0x227AB8BC
==24424==    at 0x554BBAD: ev_feed_event (ev.c:906)
==24424==    by 0x554F851: ev_run (ev.c:924)
==24424==    by 0x5541EB1: uv_run (core.c:212)
==24424==    by 0x554100C: ??? (in /home/gareth/projects/dretch-rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so)
==24424==  If you believe this happened as a result of a stack
==24424==  overflow in your program's main thread (unlikely but
==24424==  possible), you can try to increase the size of the
==24424==  main thread stack using the --main-stacksize= flag.
==24424==  The main thread stack size used in this run was 16777216.
make: *** [check-stage2-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-std-dummy] Killed

@Dretch
Copy link
Contributor Author

Dretch commented Sep 1, 2012

This now seems to be fixed - the assertion failures that were occurring in the examples above no longer seem to happen.

@Dretch Dretch closed this as completed Sep 1, 2012
brson added a commit that referenced this issue Sep 1, 2012
@brson
Copy link
Contributor

brson commented Sep 1, 2012

Thanks for following up on this @Dretch. I added the test case.

RalfJung pushed a commit to RalfJung/rust that referenced this issue Aug 11, 2023
miri: implement some `llvm.x86.sse.*` intrinsics and add tests

PR moved from rust-lang#113932.

Implements LLVM intrisics needed to run most SSE functions from `core::arch::x86{,_64}`.

Also adds miri tests for those functions (mostly copied from core_arch tests).

r? `@RalfJung`

The first commit is the same that the commit in the PR I had opened in the Rust repository. I addressed review comments in additional commits to make it easier to review. I also fixed formatting and clippy warnings.
celinval added a commit to celinval/rust-dev that referenced this issue Jun 4, 2024
I tried applying model-checking/kani#2983 fix,
however, this would require user to import
`__kani_workaround_core_assert`. To fix that, I moved the definition to
be under `kani` crate.

I replaced the existing fixme test. Initially I didn't check we had one,
and I created a second one which is simpler (no cargo needed) but that
also includes other cases.

Resolves rust-lang#2187
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation
Projects
None yet
Development

No branches or pull requests

2 participants