loom
loom copied to clipboard
[WIP] Add failing test case: atomic load on drop after panic
I'm getting a "panic-while-panicking" error when something does an atomic operation during a drop after a panic. This problem surfaced after replacing a std::sync::Arc with a loom::sync::Arc in a #[should_panic] test case.
I haven't quite investigated enough to determine a proper fix, though I suspect we need to tear down the STATE only after all the threads get dropped?
In the PR is a minimal failing test case--running the test crashes the test runner, despite the added #[should_panic].
./loom$ RUST_BACKTRACE=1 cargo test atomic_load_on_drop_in_panic_crashes -- --nocapture
# ..
thread 'atomic_load_on_drop_in_panic_crashes' panicked at 'explicit panic', tests/atomic.rs:76:9
thread panicked while panicking. aborting.
error: process didn't exit successfully: `target/debug/deps/atomic-4ad683e4748fe091 atomic_load_on_drop_in_panic_crashes --nocapture` (signal: 4, SIGILL: illegal instruction)
Full log:
./loom$ RUST_BACKTRACE=1 cargo test atomic_load_on_drop_in_panic_crashes -- --nocapture
Finished dev [unoptimized + debuginfo] target(s) in 0.02s
Running target/debug/deps/loom-4a21a40f928e0a24
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/atomic-4ad683e4748fe091
running 1 test
thread 'atomic_load_on_drop_in_panic_crashes' panicked at 'explicit panic', tests/atomic.rs:76:9
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at ~/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.34/src/backtrace/libunwind.rs:88
1: backtrace::backtrace::trace_unsynchronized
at ~/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.34/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:47
3: std::sys_common::backtrace::print
at src/libstd/sys_common/backtrace.rs:36
4: std::panicking::default_hook::{{closure}}
at src/libstd/panicking.rs:200
5: std::panicking::default_hook
at src/libstd/panicking.rs:214
6: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:477
7: std::panicking::begin_panic
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/panicking.rs:411
8: atomic::atomic_load_on_drop_in_panic_crashes::{{closure}}
at ./tests/atomic.rs:76
9: loom::model::Builder::check::{{closure}}
at ./src/model.rs:179
10: <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/liballoc/boxed.rs:787
11: <T as loom::rt::fn_box::FnBox>::call
at ./src/rt/fn_box.rs:10
12: loom::rt::scheduler::spawn_threads::{{closure}}::{{closure}}
at ./src/rt/scheduler.rs:115
13: generator::gen_impl::GeneratorImpl<A,T>::init::{{closure}}
at ~/.cargo/registry/src/github.com-1ecc6299db9ec823/generator-0.6.17/src/gen_impl.rs:146
14: core::ops::function::FnOnce::call_once{{vtable.shim}}
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ops/function.rs:235
15: <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/liballoc/boxed.rs:787
16: generator::gen_impl::gen_init::{{closure}}
at ~/.cargo/registry/src/github.com-1ecc6299db9ec823/generator-0.6.17/src/gen_impl.rs:378
17: core::ops::function::FnOnce::call_once
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ops/function.rs:235
18: std::panicking::try::do_call
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/panicking.rs:296
19: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:80
20: std::panicking::try
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/panicking.rs:275
21: std::panic::catch_unwind
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/panic.rs:394
22: generator::gen_impl::gen_init
at ~/.cargo/registry/src/github.com-1ecc6299db9ec823/generator-0.6.17/src/gen_impl.rs:392
thread 'atomic_load_on_drop_in_panic_crashes' panicked at 'cannot access a scoped thread local variable without calling `set` first', ~/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-0.1.2/src/lib.rs:186:9
stack backtrace:
0: 0x101ee5392 - backtrace::backtrace::libunwind::trace::h50be2ccf52c4f38b
at ~/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.34/src/backtrace/libunwind.rs:88
1: 0x101ee5392 - backtrace::backtrace::trace_unsynchronized::h37e5aa7f05025b64
at ~/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.34/src/backtrace/mod.rs:66
2: 0x101ee5392 - std::sys_common::backtrace::_print::h1a132f5ff57517f3
at src/libstd/sys_common/backtrace.rs:47
3: 0x101ee5392 - std::sys_common::backtrace::print::hd7293d834f1509d6
at src/libstd/sys_common/backtrace.rs:36
4: 0x101ee5392 - std::panicking::default_hook::{{closure}}::hfd04ffdb55cf7b4e
at src/libstd/panicking.rs:200
5: 0x101ee505d - std::panicking::default_hook::h0133f6f26412aeeb
at src/libstd/panicking.rs:214
6: 0x101ee5b70 - std::panicking::rust_panic_with_hook::hfbf4d22eaa2b3b02
at src/libstd/panicking.rs:477
7: 0x101ed626e - std::panicking::begin_panic::h8e231f1a7b71e8c9
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/panicking.rs:411
8: 0x101ebe063 - scoped_tls::ScopedKey<T>::with::hd06f6ae736fba8dc
at ./loom/<::std::macros::panic macros>:3
9: 0x101ebb6c7 - loom::rt::scheduler::Scheduler::with_execution::h07bcfae0a52a1aab
at ./src/rt/scheduler.rs:45
10: 0x101eb7fa5 - loom::rt::execution::h5bcf9d2b76eb8a6c
at ./src/rt/mod.rs:118
11: 0x101eb7a0d - loom::rt::branch::ha11597f086676af4
at ./src/rt/mod.rs:51
12: 0x101eb72d1 - loom::rt::object::Id::atomic_load::hf0b5df6c167f74f0
at ./src/rt/object.rs:189
13: 0x101ece15b - loom::sync::atomic::atomic::Atomic<T>::load::h665b2160c755c0ef
at ./src/sync/atomic/atomic.rs:41
14: 0x101eb8fb0 - loom::sync::atomic::int::AtomicUsize::load::h62b916452ae0124b
at ./src/sync/atomic/int.rs:34
15: 0x101e4b050 - <atomic::atomic_load_on_drop_in_panic_crashes::AtomicLoadOnDrop as core::ops::drop::Drop>::drop::h8bfcf1e166a87abc
at ./tests/atomic.rs:57
16: 0x101e4a735 - core::ptr::real_drop_in_place::ha70def3b9e51c275
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ptr/mod.rs:175
17: 0x101e4a028 - core::ptr::real_drop_in_place::h371c853a5044ef79
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ptr/mod.rs:175
18: 0x101e4a865 - core::ptr::real_drop_in_place::hb2fdb645bb857551
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ptr/mod.rs:175
19: 0x101e49cd8 - core::ptr::real_drop_in_place::h04186aecedfa591a
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ptr/mod.rs:175
20: 0x101e4a10c - core::ptr::real_drop_in_place::h4506a63fa5416d7f
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ptr/mod.rs:175
21: 0x101e4ac1d - core::ptr::real_drop_in_place::hf2fe1bc7a709f036
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ptr/mod.rs:175
22: 0x101e4ea06 - core::ptr::drop_in_place::h5370c5c7c8bd2638
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ptr/mod.rs:165
23: 0x101e4ea06 - <alloc::collections::vec_deque::VecDeque<T> as core::ops::drop::Drop>::drop::h4fe9896891a75224
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/liballoc/collections/vec_deque.rs:73
24: 0x101e4a675 - core::ptr::real_drop_in_place::h9b7bc2e3d8f6d9a9
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ptr/mod.rs:175
25: 0x101e49dce - core::ptr::real_drop_in_place::h0c788ab46f666b6a
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ptr/mod.rs:175
26: 0x101e4f465 - loom::model::Builder::check::h0ee7960ca77ba844
at ./loom/src/model.rs:190
27: 0x101e4f28c - loom::model::model::h31c7061c90e513ef
at ./loom/src/model.rs:198
28: 0x101e4afcd - atomic::atomic_load_on_drop_in_panic_crashes::hece1ac12fc1d0dd8
at ./tests/atomic.rs:61
29: 0x101e4b8f1 - atomic::atomic_load_on_drop_in_panic_crashes::{{closure}}::h99ebdddcc02909e0
at ./tests/atomic.rs:46
30: 0x101e49bd1 - core::ops::function::FnOnce::call_once::h0bc117823545eca3
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ops/function.rs:235
31: 0x101e5e98e - <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once::hfd49a6c3f2e0d999
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/liballoc/boxed.rs:787
32: 0x101ee7c2f - __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:80
33: 0x101e78297 - std::panicking::try::h68d2942b4d63deb4
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/panicking.rs:275
34: 0x101e78297 - std::panic::catch_unwind::hfea9ea3e9ce16985
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/panic.rs:394
35: 0x101e78297 - test::run_test::run_test_inner::{{closure}}::h50960bdccefe4890
at src/libtest/lib.rs:1408
36: 0x101e540e5 - std::sys_common::backtrace::__rust_begin_short_backtrace::h903849e24358c5f4
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/sys_common/backtrace.rs:77
37: 0x101e582b5 - std::thread::Builder::spawn_unchecked::{{closure}}::{{closure}}::h41bd6ee54e13b5dc
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/thread/mod.rs:470
38: 0x101e582b5 - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::h4936f23844a9934e
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/panic.rs:315
39: 0x101e582b5 - std::panicking::try::do_call::h25b5b3d132a7a2f5
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/panicking.rs:296
40: 0x101ee7c2f - __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:80
41: 0x101e588a5 - std::panicking::try::h16fbc18df085cb11
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/panicking.rs:275
42: 0x101e588a5 - std::panic::catch_unwind::h9606131b25600a0e
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/panic.rs:394
43: 0x101e588a5 - std::thread::Builder::spawn_unchecked::{{closure}}::h317c505e610dfd08
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libstd/thread/mod.rs:469
44: 0x101e588a5 - core::ops::function::FnOnce::call_once{{vtable.shim}}::h6a21792d3ef0006c
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/libcore/ops/function.rs:235
45: 0x101edb52e - <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once::ha8b8ab33c8814f1e
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/liballoc/boxed.rs:787
46: 0x101ee765e - <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once::h3eb5a968b2729d63
at /rustc/534b42394d743511db1335d5ed08d507ab7c6e73/src/liballoc/boxed.rs:787
47: 0x101ee765e - std::sys_common::thread::start_thread::h49613d362bc2f444
at src/libstd/sys_common/thread.rs:13
48: 0x101ee765e - std::sys::unix::thread::Thread::new::thread_start::h7ca3208863000f9f
at src/libstd/sys/unix/thread.rs:79
49: 0x7fff5a1b72eb - <unknown>
50: 0x7fff5a1ba249 - <unknown>
thread panicked while panicking. aborting.
error: process didn't exit successfully: `./loom/target/debug/deps/atomic-4ad683e4748fe091 atomic_load_on_drop_in_panic_crashes --nocapture` (signal: 4, SIGILL: illegal instruction)
Ah yes, I did not think about this when implementing... I'm not sure off the top of my head what is going on. Hopefully you have more insight :)
I wonder if what happens here is related to the test harness. Specifically, that the items end up getting dropped outside of loom::model somehow?
It would be really nice to have a fix for the double panic...it's definitely annoying when tests fail that way, as it's hard to get useful information out of them. Thanks for working on this!
Err, so, I'm not actually working on this, just observed what I believed to be the cause :sweat_smile: I think all that should be needed is a check for panicking somewhere in the thread_local code though.