lazy-static.rs
lazy-static.rs copied to clipboard
Multi-threading with lazy_static
Hi,
I'm trying to track down a crash in a test suite that uses lazy_static.
A Once
is being poisoned:
thread 'tests::exec_call_symbol_with_many_args_some_ignored' panicked at 'Once instance has previously been poisoned', src/libstd/sync/once.rs:395:21
stack backtrace:
0: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
1: core::fmt::write
2: std::io::Write::write_fmt
3: std::io::impls::<impl std::io::Write for alloc::boxed::Box<W>>::write_fmt
4: std::panicking::default_hook::{{closure}}
5: std::panicking::default_hook
6: std::panicking::rust_panic_with_hook
7: std::panicking::begin_panic
8: std::sync::once::Once::call_inner
9: std::sync::once::Once::call_once
at /home/vext01/research/yorick/ykrustc/src/libstd/sync/once.rs:264
10: lazy_static::lazy::Lazy<T>::get
at /home/vext01/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-1.4.0/src/inline_lazy.rs:30
11: <yktrace::tir::SIR as core::ops::deref::Deref>::deref::__stability
at /home/vext01/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-1.4.0/src/lib.rs:142
12: <yktrace::tir::SIR as core::ops::deref::Deref>::deref
at /home/vext01/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-1.4.0/src/lib.rs:144
13: yktrace::SirTraceIterator::new
at yktrace/src/lib.rs:85
14: <&dyn yktrace::SirTrace as core::iter::traits::collect::IntoIterator>::into_iter
at yktrace/src/lib.rs:62
15: yktrace::tir::TirTrace::new
at yktrace/src/tir.rs:110
16: ykcompile::tests::exec_call_symbol_with_many_args_some_ignored
at ykcompile/src/lib.rs:906
17: ykcompile::tests::exec_call_symbol_with_many_args_some_ignored::{{closure}}
at ykcompile/src/lib.rs:898
18: core::ops::function::FnOnce::call_once
at /home/vext01/research/yorick/ykrustc/src/libcore/ops/function.rs:232
19: test::run_test_in_process
If the tests are run using one thread, all is well.
So I wonder if there are some concurrency rules that need to be documented?
All I could find was:
The Deref implementation uses a hidden static variable that is guarded by an atomic check on each access.
Which suggests there is some form of multi-threading capabilities.
FWIW, my lazy_static
usage is here. It's quite long running (a few seconds) in case that is a factor.
This code has been fine up until recently. Perhaps something is racy somewhere?
It wouldn't surprise me if this is user error, so apologies if that's what it turns out to be.
Thanks.
I don't know what changed, but I can't reproduce this any more.
My theory is that the lazy_static initialiser crashed in one thread, leaving this Once
poisoned for other threads.
If that's a thing that can happen, perhaps a more user-friendly message could be printed?
In my case, this happened when the lazy_static
initializer panicked in one thread.