Skip to content

Assertion failure only when compiling with -O #2989

New issue

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

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

Already on GitHub? # to your account

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
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-codegen Area: Code generation
Projects
None yet
Development

No branches or pull requests

2 participants