denoland / deno_core

The core engine at the heart of Deno
MIT License
233 stars 76 forks source link

Memory leak in jsruntime `deno_core::ops::OpCtx::new` #806

Open spolu opened 6 days ago

spolu commented 6 days ago

In a setup where many js runtimes are created (one for each script execution served by a service) running the service in valgrind and dumping the leaks reveal some resources not being freed correctly when the jsruntime is dropped:

       Error leaked 2.5 kiB in 860 blocks
        Info at operator new(unsigned long) (vg_replace_malloc.c:483)
             at v8__CTypeInfo__New (binding.cc:2144)
             at new (fast_api.rs:64)
             at deno_core::ops::OpCtx::new (ops.rs:130)
             at deno_core::extension_set::create_op_ctxs (extension_set.rs:140)
             at deno_core::runtime::jsruntime::JsRuntime::new_inner (jsruntime.rs:722)
             at deno_core::runtime::jsruntime::JsRuntime::try_new (jsruntime.rs:624)
             at deno_core::runtime::jsruntime::JsRuntime::new (jsruntime.rs:608)
             at dust::deno::js_executor::JSExecutor::exec::{{closure}} (js_executor.rs:206)
             at <tokio::time::timeout::Timeout<T> as core::future::future::Future>::poll (timeout.rs:202)
             at dust::deno::js_executor::JSExecutor::run::{{closure}}::{{closure}} (js_executor.rs:258)
             at <core::pin::Pin<P> as core::future::future::Future>::poll (future.rs:123)
             at tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}::{{closure}}::{{closure}} (mod.rs:659)
       Error leaked 4.7 kiB in 15 blocks
        Info at calloc (vg_replace_malloc.c:1595)
             at calloc (rtld-malloc.h:44)
             at allocate_dtv (dl-tls.c:370)
             at _dl_allocate_tls (dl-tls.c:629)
             at allocate_stack (allocatestack.c:429)
             at pthread_create@@GLIBC_2.34 (pthread_create.c:655)
             at v8::base::Thread::Start() (platform-posix.cc:1223)
             at v8::platform::DefaultWorkerThreadsTaskRunner::DefaultWorkerThreadsTaskRunner(unsigned int, double (*)(), v8::base::Thread::Priority) (default-worker-threads-task-runner.cc:18)
             at v8::platform::DefaultPlatform::EnsureBackgroundTaskRunnerInitialized() (default-platform.cc:141)
             at v8::platform::NewDefaultPlatform(int, v8::platform::IdleTaskSupport, v8::platform::InProcessStackDumping, std::Cr::unique_ptr<v8::TracingController, std::Cr::default_delete<v8::TracingController> >, v8::platform::PriorityMode) (default-platform.cc:54)
             at new (platform.rs:133)
             at new_default_platform (platform.rs:80)
             at deno_core::runtime::setup::v8_init::{{closure}} (setup.rs:56)
             at core::option::Option<T>::unwrap_or_else (option.rs:977)
             at deno_core::runtime::setup::v8_init (setup.rs:51)
             at deno_core::runtime::setup::init_v8::{{closure}} (setup.rs:82)
             at std::sync::once::Once::call_once::{{closure}} (once.rs:149)
       Error leaked 5.2 kiB in 36 blocks
        Info at malloc (vg_replace_malloc.c:442)
             at alloc::alloc::alloc (alloc.rs:100)
             at alloc::alloc::Global::alloc_impl (alloc.rs:183)
             at <alloc::alloc::Global as core::alloc::Allocator>::allocate (alloc.rs:243)
             at hashbrown::raw::alloc::inner::do_alloc (alloc.rs:15)
             at hashbrown::raw::RawTableInner::new_uninitialized (mod.rs:1752)
             at hashbrown::raw::RawTableInner::fallible_with_capacity (mod.rs:1790)
             at hashbrown::raw::RawTableInner::prepare_resize (mod.rs:2869)
             at resize_inner<alloc::alloc::Global> (mod.rs:3065)
             at reserve_rehash_inner<alloc::alloc::Global> (mod.rs:2955)
             at hashbrown::raw::RawTable<T,A>::reserve_rehash (mod.rs:1233)
             at hashbrown::raw::RawTable<T,A>::reserve (mod.rs:1181)
             at hashbrown::raw::RawTable<T,A>::find_or_find_insert_slot (mod.rs:1415)
             at hashbrown::map::HashMap<K,V,S,A>::insert (map.rs:1754)
       Error leaked 19.6 kiB in 860 blocks
        Info at operator new(unsigned long) (vg_replace_malloc.c:483)
             at v8__CFunctionInfo__New (binding.cc:2167)
             at new (fast_api.rs:42)
             at deno_core::ops::OpCtx::new (ops.rs:135)
             at deno_core::extension_set::create_op_ctxs (extension_set.rs:140)
             at deno_core::runtime::jsruntime::JsRuntime::new_inner (jsruntime.rs:722)
             at deno_core::runtime::jsruntime::JsRuntime::try_new (jsruntime.rs:624)
             at deno_core::runtime::jsruntime::JsRuntime::new (jsruntime.rs:608)
             at dust::deno::js_executor::JSExecutor::exec::{{closure}} (js_executor.rs:206)
             at <tokio::time::timeout::Timeout<T> as core::future::future::Future>::poll (timeout.rs:202)
             at dust::deno::js_executor::JSExecutor::run::{{closure}}::{{closure}} (js_executor.rs:258)
             at <core::pin::Pin<P> as core::future::future::Future>::poll (future.rs:123)
             at tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}::{{closure}}::{{closure}} (mod.rs:659)

Can be reproduced with the code here: https://github.com/dust-tt/dust/blob/main/core/src/deno/js_executor.rs#L79-L135

lucacasonato commented 1 day ago

cc @littledivy