sway icon indicating copy to clipboard operation
sway copied to clipboard

Garbage collection causes panic when accessing `ParsedDeclId` from `ParsedDeclEngine`

Open JoshuaBatty opened this issue 1 year ago • 4 comments

Today I noticed a panic when using the language server. It only seemed to happen very rarely so I wrote the below test.

Also, running the test with a single thread like below seemed to trigger the error more frequently.

cargo test did_change_stress_test_random -- --nocapture --test-threads=1

#[tokio::test]
#[allow(dead_code)]
async fn did_change_stress_test_random() {
    set_panic_hook();

    let (mut service, _) = LspService::build(ServerState::new)
        .custom_method("sway/metrics", ServerState::metrics)
        .finish();
    let bench_dir = sway_workspace_dir().join("sway-lsp/tests/fixtures/benchmark");
    let uri = init_and_open(&mut service, bench_dir.join("src/main.sw")).await;
    let times = 40000;
    for version in 0..times {
        eprintln!("version: {}", version);
        let _ = lsp::did_change_request(&mut service, &uri, version + 1).await;
        if version == 0 {
            service.inner().wait_for_parsing().await;
        }
        let metrics = lsp::metrics_request(&mut service, &uri).await;
        for (path, metrics) in metrics {
            if path.contains("sway-lib-core") || path.contains("sway-lib-std") {
                assert!(metrics.reused_modules >= 1);
            }
        }
        // wait for a random amount of time between 1-30ms
        let wait_time = rand::random::<u64>() % 30 + 1;
        tokio::time::sleep(tokio::time::Duration::from_millis(wait_time)).await;

        // there is a 10% chance that a longer 300-1000ms wait will be added
        if rand::random::<u64>() % 10 < 1 {
            let wait_time = rand::random::<u64>() % 700 + 300;
            tokio::time::sleep(tokio::time::Duration::from_millis(wait_time)).await;
        }
    }
    shutdown_and_exit(&mut service).await;
}

fn set_panic_hook() {
    std::env::set_var("RUST_BACKTRACE", "1");
    let default_panic = std::panic::take_hook();

    std::panic::set_hook(Box::new(move |panic_info| {
        eprintln!("PANIC!!!!!!!!!!!!!!!");
        // Print the panic message
        default_panic(panic_info);

        eprintln!("exiting");
        std::process::exit(1);
    }));
}

And below is the output that caught the panic with the backtrace. It seems that in this instance it took 3243 didChange events for the ParsedDeclEngine to not contain an assumed valid ParsedDeclId for the let struct_decl = ctx.engines.pe().get_struct(self); to work.

I don't understand why calling GC the thousands of times before hand didn't lead to this ParsedDeclId not being removed. @tritao do you have any suggestions on what might be happening here? I have a branch here if you want to try recreating locally.

Garbage collection complete: version 3243
Starting compilation
Finished compilation
Starting traversal
PANIC!!!!!!!!!!!!!!!
PANIC!!!!!!!!!!!!!!!
PANIC!!!!!!!!!!!!!!!
PANIC!!!!!!!!!!!!!!!
thread 'thread 'PANIC!!!!!!!!!!!!!!!
<unnamed><unnamed>' panicked at thread 'thread 'sway-core/src/concurrent_slab.rs' panicked at <unnamed><unnamed>:sway-core/src/concurrent_slab.rs90:PANIC!!!!!!!!!!!!!!!
90thread '<unnamed>' panicked at sway-core/src/concurrent_slab.rs:90:thread '14' panicked at <unnamed>:
sway-core/src/concurrent_slab.rsPANIC!!!!!!!!!!!!!!!
' panicked at ::no entry found for keythread '
90<unnamed>::14:
sway-core/src/concurrent_slab.rsno entry found for key:
' panicked at sway-core/src/concurrent_slab.rsPANIC!!!!!!!!!!!!!!!
90:14:thread '14:
no entry found for key
90<unnamed>:' panicked at sway-core/src/concurrent_slab.rs14:
14no entry found for key:
:no entry found for key90
:' panicked at PANIC!!!!!!!!!!!!!!!
stack backtrace:
:

thread '<unnamed>' panicked at 14sway-core/src/concurrent_slab.rs:
PANIC!!!!!!!!!!!!!!!
thread '<unnamed>:' panicked at sway-core/src/concurrent_slab.rs90no entry found for keysway-core/src/concurrent_slab.rsno entry found for key:
90:14:
no entry found for key:

:90:14:
no entry found for key
14:
no entry found for key
version: 3243
version: 3244
version: 3245
version: 3246
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_display
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:168:5
   3: core::panicking::panic_str
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:152:5
   4: core::option::expect_failed
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/option.rs:1988:5
   5: core::option::Option<T>::expect
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/option.rs:898:21
   6: <std::collections::hash::map::HashMap<K,V,S> as core::ops::index::Index<&Q>>::index
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/collections/hash/map.rs:1341:23
   7: sway_core::concurrent_slab::ConcurrentSlab<T>::get
             at /Users/joshuabatty/Documents/rust/fuel/sway/sway-core/src/concurrent_slab.rs:90:14
   8: <sway_core::decl_engine::parsed_engine::ParsedDeclEngine as sway_core::decl_engine::parsed_engine::ParsedDeclEngineGet<sway_core::decl_engine::parsed_id::ParsedDeclId<sway_core::language::parsed::declaration::function::FunctionDeclaration>,sway_core::language::parsed::declaration::function::FunctionDeclaration>>::get
             at /Users/joshuabatty/Documents/rust/fuel/sway/sway-core/src/decl_engine/parsed_engine.rs:59:17
   9: sway_core::decl_engine::parsed_engine::ParsedDeclEngine::get_function
             at /Users/joshuabatty/Documents/rust/fuel/sway/sway-core/src/decl_engine/parsed_engine.rs:185:9
  10: sway_lsp::traverse::parsed_tree::<impl sway_lsp::traverse::Parse for sway_core::decl_engine::parsed_id::ParsedDeclId<sway_core::language::parsed::declaration::function::FunctionDeclaration>>::parse
             at ./src/traverse/parsed_tree.rs:734:23
  11: sway_lsp::traverse::parsed_tree::<impl sway_lsp::traverse::Parse for sway_core::language::parsed::declaration::Declaration>::parse
             at ./src/traverse/parsed_tree.rs:124:58
  12: sway_lsp::traverse::parsed_tree::<impl sway_lsp::traverse::Parse for sway_core::language::parsed::AstNode>::parse
             at ./src/traverse/parsed_tree.rs:108:57
  13: sway_lsp::traverse::parsed_tree::ParsedTree::traverse_node
             at ./src/traverse/parsed_tree.rs:53:9
  14: sway_lsp::core::session::traverse::{{closure}}
             at ./src/core/session.rs:415:59
  15: sway_lsp::core::session::parse_ast_to_tokens::{{closure}}
             at ./src/core/session.rs:488:35
  16: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &F>::call_mut
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/ops/function.rs:272:13
  17: <core::slice::iter::Iter<T> as core::iter::traits::iterator::Iterator>::for_each
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/slice/iter/macros.rs:254:21
  18: <rayon::iter::for_each::ForEachConsumer<F> as rayon::iter::plumbing::Folder<T>>::consume_iter
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.8.0/src/iter/for_each.rs:55:9
  19: rayon::iter::plumbing::Producer::fold_with
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.8.0/src/iter/plumbing/mod.rs:110:9
  20: rayon::iter::plumbing::bridge_producer_consumer::helper
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.8.0/src/iter/plumbing/mod.rs:438:13
  21: rayon::iter::plumbing::bridge_producer_consumer::helper::{{closure}}
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.8.0/src/iter/plumbing/mod.rs:418:21
  22: rayon_core::join::join_context::call_a::{{closure}}
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/join/mod.rs:124:17
  23: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panic/unwind_safe.rs:271:9
  24: std::panicking::try::do_call
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:504:40
  25: ___rust_try
  26: std::panicking::try
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:468:19
  27: std::panic::catch_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panic.rs:142:14
  28: rayon_core::unwind::halt_unwinding
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/unwind.rs:17:5
  29: rayon_core::join::join_context::{{closure}}
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/join/mod.rs:142:24
  30: rayon_core::registry::in_worker
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/registry.rs:950:13
  31: rayon_core::join::join_context
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/join/mod.rs:132:5
  32: rayon::iter::plumbing::bridge_producer_consumer::helper
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.8.0/src/iter/plumbing/mod.rs:416:47
  33: rayon::iter::plumbing::bridge_producer_consumer::helper::{{closure}}
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.8.0/src/iter/plumbing/mod.rs:418:21
  34: rayon_core::join::join_context::call_a::{{closure}}
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/join/mod.rs:124:17
  35: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panic/unwind_safe.rs:271:9
  36: std::panicking::try::do_call
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:504:40
  37: ___rust_try
  38: std::panicking::try
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:468:19
  39: std::panic::catch_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panic.rs:142:14
  40: rayon_core::unwind::halt_unwinding
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/unwind.rs:17:5
  41: rayon_core::join::join_context::{{closure}}
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/join/mod.rs:142:24
  42: rayon_core::registry::in_worker
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/registry.rs:950:13
  43: rayon_core::join::join_context
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/join/mod.rs:132:5
  44: rayon::iter::plumbing::bridge_producer_consumer::helper
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.8.0/src/iter/plumbing/mod.rs:416:47
  45: rayon::iter::plumbing::bridge_producer_consumer::helper::{{closure}}
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.8.0/src/iter/plumbing/mod.rs:427:21
  46: rayon_core::join::join_context::call_b::{{closure}}
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/join/mod.rs:129:25
  47: rayon_core::job::JobResult<T>::call::{{closure}}
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/job.rs:218:41
  48: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panic/unwind_safe.rs:271:9
  49: std::panicking::try::do_call
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:504:40
  50: ___rust_try
  51: std::panicking::try
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:468:19
  52: std::panic::catch_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panic.rs:142:14
  53: rayon_core::unwind::halt_unwinding
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/unwind.rs:17:5
  54: rayon_core::job::JobResult<T>::call
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/job.rs:218:15
  55: <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/job.rs:120:32
  56: rayon_core::job::JobRef::execute
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/job.rs:64:9
  57: rayon_core::registry::WorkerThread::execute
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/registry.rs:859:9
  58: rayon_core::registry::WorkerThread::wait_until_cold
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/registry.rs:793:21
  59: rayon_core::registry::WorkerThread::wait_until
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/registry.rs:768:13
  60: rayon_core::registry::WorkerThread::wait_until_out_of_work
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/registry.rs:817:9
  61: rayon_core::registry::main_loop
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/registry.rs:922:5
  62: rayon_core::registry::ThreadBuilder::run
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/registry.rs:52:18
  63: <rayon_core::registry::DefaultSpawn as rayon_core::registry::ThreadSpawn>::spawn::{{closure}}
             at /Users/joshuabatty/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-core-1.12.0/src/registry.rs:97:20
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
exiting
stack backtrace:
error: test failed, to rerun pass `--test lib`

JoshuaBatty avatar Jan 31 '24 05:01 JoshuaBatty

请问这个是不是还没有实现?

wxhwen avatar Feb 04 '24 07:02 wxhwen

"This issue has been inactive for a prolonged period and will be closed automatically in 3 days." "该问题已长时间处于闲置状态,3 天后将自动关闭。"

github-actions[bot] avatar Jul 22 '24 19:07 github-actions[bot]