Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Garbage collection causes panic when accessing ParsedDeclId from ParsedDeclEngine #5531

Closed
JoshuaBatty opened this issue Jan 31, 2024 · 6 comments
Assignees
Labels
bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen language server LSP server

Comments

@JoshuaBatty
Copy link
Member

JoshuaBatty commented Jan 31, 2024

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 JoshuaBatty added bug Something isn't working language server LSP server compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen labels Jan 31, 2024
@JoshuaBatty JoshuaBatty changed the title Garbage collection causes panic when accessing DeclId's from ParsedDeclEngine Garbage collection causes panic when accessing ParsedDeclId from ParsedDeclEngine Jan 31, 2024
@tritao tritao self-assigned this Jan 31, 2024
@tritao
Copy link
Contributor

tritao commented Feb 1, 2024

So, I was easily able to reproduce this with your branch. Been investigating why this happens, still not 100% sure, but I cannot reproduce it with the random waits removed. That makes me suspect this might be due to a concurrency issue.

Do you think that could be the case? With the current LSP architecture, can we somehow be clearing the parsed decl engine in one task/thread, while another is traversing the parsed tree?

@JoshuaBatty
Copy link
Member Author

Yeah i think you might be correct, I commented out clearing the parsed_decl_engine and managed to also hit a similar panic with the type engine indexing OOB.

Screenshot 2024-02-02 at 1 11 26 pm
Garbage collection complete: version 2858
Starting compilation
version: 2858
Failed to compile: version Some(2858)
Garbage collection complete: version 2859
Starting compilation
Finished compilation
Starting traversal
PANIC!!!!!!!!!!!!!!!
thread '<unnamed>' panicked at PANIC!!!!!!!!!!!!!!!
sway-core/src/concurrent_slab.rs:90thread ':<unnamed>14:
no entry found for key' panicked at 
sway-core/src/concurrent_slab.rs:90:14:
no entry found for key
PANIC!!!!!!!!!!!!!!!
thread '<unnamed>' panicked at sway-core/src/concurrent_slab.rsPANIC!!!!!!!!!!!!!!!
thread '<unnamed>' panicked at sway-core/src/concurrent_slab.rs:90::PANIC!!!!!!!!!!!!!!!
14:
PANIC!!!!!!!!!!!!!!!
no entry found for keythread '<unnamed>
' panicked at sway-core/src/concurrent_slab.rs:90:14:
no entry found for key
thread '<unnamed>' panicked at PANIC!!!!!!!!!!!!!!!
sway-core/src/concurrent_slab.rs:90:14:
no entry found for key
90thread ':<unnamed>14' panicked at :
sway-core/src/concurrent_slab.rsno entry found for key:
90:14:
no entry found for key
stack backtrace:
PANIC!!!!!!!!!!!!!!!
thread '<unnamed>PANIC!!!!!!!!!!!!!!!
thread '<unnamed>' panicked at ' panicked at sway-core/src/concurrent_slab.rssway-core/src/concurrent_slab.rs:90:14:
no entry found for key
PANIC!!!!!!!!!!!!!!!
thread '<unnamed>' panicked at sway-core/src/concurrent_slab.rs:90:14:
:no entry found for key90
:14:
no entry found for key
   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::type_system::engine::TypeEngine::get
             at /Users/joshuabatty/Documents/rust/fuel/sway/sway-core/src/type_system/engine.rs:92:9
   9: sway_lsp::traverse::parsed_tree::<impl sway_lsp::traverse::Parse for sway_core::type_system::ast_elements::type_argument::TypeArgument>::parse
             at ./src/traverse/parsed_tree.rs:1071:25
  10: sway_lsp::traverse::parsed_tree::<impl sway_lsp::traverse::Parse for sway_core::language::parsed::declaration::enum::EnumVariant>::parse
             at ./src/traverse/parsed_tree.rs:1052:9
  11: sway_lsp::traverse::parsed_tree::<impl sway_lsp::traverse::Parse for sway_core::decl_engine::parsed_id::ParsedDeclId<sway_core::language::parsed::declaration::enum::EnumDeclaration>>::parse::{{closure}}
             at ./src/traverse/parsed_tree.rs:822:13

Makes sense why it wasn't crashing without the random wait times removed as compilation is cancelled before it has a chance to start otherwise.

There is only a single compilation thread so it's not obvious to me how the engines could be a concurrency issue but I'll see if I can dig a bit deeper into that thread now.

@JoshuaBatty
Copy link
Member Author

JoshuaBatty commented Feb 2, 2024

Ok have dug in a bit further here. below is the output of a typical successful compilation

New compilation msg: cloning engines.. : version Some(2081)
Cloned engines: version Some(2081)
Starting Garbage collection: version 2081
Garbage collecting workspace at "/private/var/folders/3z/79mvj_fn5298rz6zb4gnctw00000gn/T/SWAY_LSP_TEMP_DIRG979QR/benchmark"
Module ID: Some(ModuleId { id: 3 })
Engine theading : Clearing module ModuleId { id: 3 }
TE In slab, 254046 items were retained and 2330 items were removed.
TE In id_map, 266 items were retained and 24 items were removed.
DE In parents, 71454 items were retained and 56 items were removed.
DE In function_slab, 70580 items were retained and 107 items were removed.
DE In trait_slab, 26 items were retained and 0 items were removed.
DE In trait_fn_slab, 1660 items were retained and 0 items were removed.
DE In trait_type_slab, 0 items were retained and 0 items were removed.
DE In impl_trait_slab, 342 items were retained and 20 items were removed.
DE In struct_slab, 12943 items were retained and 60 items were removed.
DE In storage_slab, 0 items were retained and 0 items were removed.
DE In abi_slab, 0 items were retained and 0 items were removed.
DE In constant_slab, 72 items were retained and 1 items were removed.
DE In enum_slab, 48221 items were retained and 130 items were removed.
DE In type_alias_slab, 1 items were retained and 0 items were removed.
PDE In variable_slab, 1495 items were retained and 1241 items were removed.
PDE In function_slab, 756 items were retained and 51 items were removed.
PDE In trait_slab, 26 items were retained and 0 items were removed.
PDE In trait_fn_slab, 0 items were retained and 0 items were removed.
PDE In trait_type_slab, 0 items were retained and 0 items were removed.
PDE In impl_trait_slab, 236 items were retained and 20 items were removed.
PDE In impl_self_slab, 53 items were retained and 0 items were removed.
PDE In struct_slab, 20 items were retained and 10 items were removed.
PDE In storage_slab, 0 items were retained and 0 items were removed.
PDE In abi_slab, 0 items were retained and 0 items were removed.
PDE In constant_slab, 72 items were retained and 1 items were removed.
PDE In enum_slab, 13 items were retained and 10 items were removed.
PDE In type_alias_slab, 1 items were retained and 0 items were removed.
Garbage collection complete: version 2081
call parse project: version Some(2081)
Starting compilation
Finished compilation
TE num inserts: 4873
PDE variable_slab num_inserts: 1241
PDE function_slab num_inserts: 51
PDE trait_slab num_inserts: 0
PDE trait_fn_slab num_inserts: 0
PDE trait_type_slab num_inserts: 0
PDE impl_trait_slab num_inserts: 20
PDE impl_self_slab num_inserts: 0
PDE struct_slab num_inserts: 10
PDE storage_slab num_inserts: 0
PDE abi_slab num_inserts: 0
PDE constant_slab num_inserts: 1
PDE enum_slab num_inserts: 10
PDE type_alias_slab num_inserts: 0
PDE num inserts: ()
Starting traversal

But here is the output when it fails

New compilation msg: cloning engines.. : version Some(2144)
Cloned engines: version Some(2144)
Starting Garbage collection: version 2144
Garbage collecting workspace at "/private/var/folders/3z/79mvj_fn5298rz6zb4gnctw00000gn/T/SWAY_LSP_TEMP_DIRG979QR/benchmark"
Module ID: Some(ModuleId { id: 3 })
Engine theading : Clearing module ModuleId { id: 3 }
TE In slab, 256589 items were retained and 2330 items were removed.
TE In id_map, 266 items were retained and 24 items were removed.
DE In parents, 71734 items were retained and 56 items were removed.
DE In function_slab, 70840 items were retained and 107 items were removed.
DE In trait_slab, 26 items were retained and 0 items were removed.
DE In trait_fn_slab, 1680 items were retained and 0 items were removed.
DE In trait_type_slab, 0 items were retained and 0 items were removed.
DE In impl_trait_slab, 342 items were retained and 20 items were removed.
DE In struct_slab, 12995 items were retained and 60 items were removed.
DE In storage_slab, 0 items were retained and 0 items were removed.
DE In abi_slab, 0 items were retained and 0 items were removed.
DE In constant_slab, 72 items were retained and 1 items were removed.
DE In enum_slab, 48221 items were retained and 130 items were removed.
DE In type_alias_slab, 1 items were retained and 0 items were removed.
PDE In variable_slab, 1495 items were retained and 1241 items were removed.
PDE In function_slab, 756 items were retained and 51 items were removed.
PDE In trait_slab, 26 items were retained and 0 items were removed.
PDE In trait_fn_slab, 0 items were retained and 0 items were removed.
PDE In trait_type_slab, 0 items were retained and 0 items were removed.
PDE In impl_trait_slab, 236 items were retained and 20 items were removed.
PDE In impl_self_slab, 53 items were retained and 0 items were removed.
PDE In struct_slab, 20 items were retained and 10 items were removed.
PDE In storage_slab, 0 items were retained and 0 items were removed.
PDE In abi_slab, 0 items were retained and 0 items were removed.
PDE In constant_slab, 72 items were retained and 1 items were removed.
PDE In enum_slab, 13 items were retained and 10 items were removed.
PDE In type_alias_slab, 1 items were retained and 0 items were removed.
Garbage collection complete: version 2144
call parse project: version Some(2144)
Starting compilation
Finished compilation
TE num inserts: 1
PDE variable_slab num_inserts: 0
PDE function_slab num_inserts: 0
PDE trait_slab num_inserts: 0
PDE trait_fn_slab num_inserts: 0
PDE trait_type_slab num_inserts: 0
PDE impl_trait_slab num_inserts: 0
PDE impl_self_slab num_inserts: 0
PDE struct_slab num_inserts: 0
PDE storage_slab num_inserts: 0
PDE abi_slab num_inserts: 0
PDE constant_slab num_inserts: 1
PDE enum_slab num_inserts: 0
PDE type_alias_slab num_inserts: 0
PDE num inserts: ()
Starting traversal
Index 1961 not found in slab. Current slab size: 20 | keys [10, 16, 13, 2, 4, 15, 19, 1, 5, 9, 18, 20, 7, 6, 17, 11, 8, 14, 3, 12] | last_id RwLock { data: 1990, poisoned: false, .. } | num_inserts: 0 | last_inserted_len 0 | last_inserted_keys {}
PANIC!!!!!!!!!!!!!!!

Notice how when successful we get TE num inserts: 4873 and when it fails it prints TE num inserts: 1. I've added another field to the slab to track how many times the insert and insert_arc methods get called during compilation. It seems for some reason these are not getting called which is leading to the crash.

@tritao i've pushed another commit to my branch that has these new debug prints.

@JoshuaBatty
Copy link
Member Author

Ok, I think I found the culprit but I don't understand why it's happening.

If I removed the Arc around the fields in the QueryEngine and instead clone the RwLocks then i'm unable to reproduce the error. @tritao do you have any instinct into why this might be the case?

impl Clone for QueryEngine {
    fn clone(&self) -> Self {
        Self {
            parse_module_cache: RwLock::new(self.parse_module_cache.read().unwrap().clone()),
            programs_cache: RwLock::new(self.programs_cache.read().unwrap().clone()),
        }
    }
}

@JoshuaBatty JoshuaBatty mentioned this issue Feb 5, 2024
7 tasks
@JoshuaBatty
Copy link
Member Author

I've reverted the optimization in #5548 for now. We should still try and get the optimization back in once we understand how to avoid this crash from happening.

JoshuaBatty added a commit that referenced this issue Feb 5, 2024
## Description
This was added as an optimization in #5472. However, it seems to be the
cause of a transient bug that is causing the language server to crash
outlined in #5531.

We should revert this optimization until we understand how to avoid this
crash from happening. cc @tritao

## Checklist

- [x] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
@JoshuaBatty
Copy link
Member Author

This should all be resolved now as of #5813

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen language server LSP server
Projects
None yet
Development

No branches or pull requests

2 participants