-
Notifications
You must be signed in to change notification settings - Fork 547
Closed
Description
In xiph/rav1e#2851 NixOS found out the crash of rayon-1.5.1
on rav1e
doctests. Here is extracted reproducer:
# cat Cargo.toml
[package]
name = "bug"
version = "0.1.0"
edition = "2018"
[dependencies]
rayon = "~1.5.1"
[profile.dev]
#debug = true
#incremental = true
#debug-assertions = true
lto = "thin"
opt-level = 2
overflow-checks = false
codegen-units = 256
// cat src/lib.rs
use rayon::iter::IntoParallelIterator;
use rayon::iter::ParallelIterator;
/// # Examples
///
/// ```
/// use bug::do_bug;
///
/// # fn main() {
/// bug::do_bug()
/// # }
/// ```
pub fn do_bug() {
(0..1).into_par_iter().for_each(|_| {});
(0..1).into_par_iter().for_each(|_| {});
(0..1).into_par_iter().for_each(|_| {});
}
Reproducer run:
$ cargo test --doc
Updating crates.io index
Compiling autocfg v1.0.1
Compiling crossbeam-utils v0.8.6
Compiling lazy_static v1.4.0
Compiling cfg-if v1.0.0
Compiling crossbeam-epoch v0.9.6
Compiling libc v0.2.112
Compiling scopeguard v1.1.0
Compiling rayon-core v1.9.1
Compiling either v1.6.1
Compiling memoffset v0.6.5
Compiling rayon v1.5.1
Compiling crossbeam-channel v0.5.2
Compiling crossbeam-deque v0.8.1
Compiling num_cpus v1.13.1
Compiling bug v0.1.0 (/tmp/xx)
Finished test [optimized + debuginfo] target(s) in 5.26s
Doc-tests bug
running 1 test
test src/lib.rs - do_bug (line 6) ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.10s
$ cargo test --doc
Finished test [optimized + debuginfo] target(s) in 0.01s
Doc-tests bug
running 1 test
test src/lib.rs - do_bug (line 6) ... FAILED
failures:
---- src/lib.rs - do_bug (line 6) stdout ----
Test executable failed (terminated by signal).
failures:
src/lib.rs - do_bug (line 6)
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.20s
error: test failed, to rerun pass '--doc'
Notes:
- Sometimes it needs a few runs to crash
Cargo.toml
enabledlto = "thin"; opt-level = 2
but be careful:rustdoc
does not seem to passopt-level =
to test itself, only anlto
part. That makes it a bit hard to reason about optimisation mix.
Attempt at fetching backtrace:
Thread 2 "rust_out" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffb9a360640 (LWP 662570)]
0x00007ffb9a35f8e8 in ?? ()
(gdb) bt
#0 0x00007ffb9a35f8e8 in ?? ()
#1 0x00007ffb9a3605f8 in ?? ()
#2 0x00007ffb9a35fa30 in ?? ()
#3 0x0000556a1c6df25c in rayon_core::registry::WorkerThread::set_current (thread=0x7ffb9a35f500) at /home/slyfox/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:636
#4 rayon_core::registry::main_loop (registry=..., index=0, worker=...) at /home/slyfox/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:807
#5 rayon_core::registry::ThreadBuilder::run (self=...) at /home/slyfox/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:55
#6 0x0000556a1c70206d in rayon_core::registry::{impl#2}::spawn::{closure#0} () at /home/slyfox/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:100
#7 std::sys_common::backtrace::__rust_begin_short_backtrace<rayon_core::registry::{impl#2}::spawn::{closure#0}, ()> (f=...) at /build/rustc-1.57.0-src/library/std/src/sys_common/backtrace.rs:123
#8 0x0000556a1c6e493c in std::thread::{impl#0}::spawn_unchecked::{closure#1}::{closure#0}<rayon_core::registry::{impl#2}::spawn::{closure#0}, ()> () at /build/rustc-1.57.0-src/library/std/src/thread/mod.rs:483
#9 core::panic::unwind_safe::{impl#23}::call_once<(), std::thread::{impl#0}::spawn_unchecked::{closure#1}::{closure#0}> (self=..., _args=<optimized out>)
at /build/rustc-1.57.0-src/library/core/src/panic/unwind_safe.rs:271
#10 0x0000556a1c6e34cf in std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<std::thread::{impl#0}::spawn_unchecked::{closure#1}::{closure#0}>, ()> (data=<optimized out>)
at /build/rustc-1.57.0-src/library/std/src/panicking.rs:403
#11 std::panicking::try<(), core::panic::unwind_safe::AssertUnwindSafe<std::thread::{impl#0}::spawn_unchecked::{closure#1}::{closure#0}>> (f=...) at /build/rustc-1.57.0-src/library/std/src/panicking.rs:367
#12 0x0000556a1c6fbb30 in std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<std::thread::{impl#0}::spawn_unchecked::{closure#1}::{closure#0}>, ()> (f=...)
at /build/rustc-1.57.0-src/library/std/src/panic.rs:133
#13 0x0000556a1c6da205 in std::thread::{impl#0}::spawn_unchecked::{closure#1}<rayon_core::registry::{impl#2}::spawn::{closure#0}, ()> () at /build/rustc-1.57.0-src/library/std/src/thread/mod.rs:482
#14 core::ops::function::FnOnce::call_once<std::thread::{impl#0}::spawn_unchecked::{closure#1}, ()> () at /build/rustc-1.57.0-src/library/core/src/ops/function.rs:227
#15 0x0000556a1c761515 in std::sys::unix::thread::Thread::new::thread_start ()
#16 0x00007ffb9a67cd40 in start_thread () from /nix/store/s9qbqh7gzacs7h68b2jfmn9l6q4jwfjz-glibc-2.33-59/lib/libpthread.so.0
#17 0x00007ffb9a46343f in clone () from /nix/store/s9qbqh7gzacs7h68b2jfmn9l6q4jwfjz-glibc-2.33-59/lib/libc.so.6
Echoing comment xiph/rav1e#2851 (comment) here:
"""
Specifically rayon-core-1.9.1/src/registry.rs:
/// Sets `self` as the worker thread index for the current thread.
/// This is done during worker thread startup.
unsafe fn set_current(thread: *const WorkerThread) {
WORKER_THREAD_STATE.with(|t| {
assert!(t.get().is_null());
t.set(thread);
});
}
...
unsafe fn main_loop(worker: Worker<JobRef>, registry: Arc<Registry>, index: usize) {
let worker_thread = &WorkerThread {
worker,
fifo: JobFifo::new(),
index,
rng: XorShift64Star::new(),
registry: registry.clone(),
};
WorkerThread::set_current(worker_thread);
...
Does rust guarantee that raw worker_thread will point to fully constructed object? Or could actual initialization move downward a bit?
"""
Thank you!
Metadata
Metadata
Assignees
Labels
No labels