Skip to content

Small memory leaks on EnvironmentTest.InspectorMultipleEmbeddedEnvironments #32415

Closed
@mmarchini

Description

@mmarchini

ASAN shows two memory leaks for EnvironmentTest.InspectorMultipleEmbeddedEnvironments. The first one is:

Direct leak of 16 byte(s) in 1 object(s) allocated from:                                                                                                                                                                                                       
    #0 0xe0866d in operator new(unsigned long) (/nodejs/out/Debug/cctest+0xe0866d)                                                                                                                                                                             
    #1 0x25189ea in node::inspector::MainThreadInterface::Post(std::unique_ptr<node::inspector::Request, std::default_delete<node::inspector::Request> >) /nodejs/out/Debug/../../src/inspector/main_thread_interface.cc:236:11                                
    #2 0x251aa16 in node::inspector::MainThreadHandle::Post(std::unique_ptr<node::inspector::Request, std::default_delete<node::inspector::Request> >) /nodejs/out/Debug/../../src/inspector/main_thread_interface.cc:342:17                                   
    #3 0x2538623 in node::inspector::protocol::TracingAgent::~TracingAgent() /nodejs/out/Debug/../../src/inspector/tracing_agent.cc:123:17                                                                                                                     
    #4 0x25388bb in node::inspector::protocol::TracingAgent::~TracingAgent() /nodejs/out/Debug/../../src/inspector/tracing_agent.cc:121:31                                                                                                                     
    #5 0x24adbbf in std::default_delete<node::inspector::protocol::TracingAgent>::operator()(node::inspector::protocol::TracingAgent*) const /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unique_ptr.h:81:2                           
    #6 0x24ad7e1 in std::unique_ptr<node::inspector::protocol::TracingAgent, std::default_delete<node::inspector::protocol::TracingAgent> >::reset(node::inspector::protocol::TracingAgent*) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/b
its/unique_ptr.h:394:4                                                                                                                                                                                                                                         
    #7 0x2497b50 in node::inspector::(anonymous namespace)::ChannelImpl::~ChannelImpl() /nodejs/out/Debug/../../src/inspector_agent.cc:255:20                                                                                                                  
    #8 0x2497dcb in node::inspector::(anonymous namespace)::ChannelImpl::~ChannelImpl() /nodejs/out/Debug/../../src/inspector_agent.cc:253:27                                                                                                                  
    #9 0x249b3bf in std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl>::operator()(node::inspector::(anonymous namespace)::ChannelImpl*) const /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unique_ptr.h:81:2   
    #10 0x2496fb9 in std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> >::~unique_ptr() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/uniqu
e_ptr.h:284:4                                                                                                                                                                                                                                                  
    #11 0x249d45d in std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >::~pair() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include
/c++/9/bits/stl_pair.h:208:12                                                                                                                                                                                                                                  
    #12 0x249d438 in void __gnu_cxx::new_allocator<std::__detail::_Hash_node<std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >, false> >::
destroy<std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > > >(std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::C
hannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >*) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:153:10                                                                         
    #13 0x249d3bf in void std::allocator_traits<std::allocator<std::__detail::_Hash_node<std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >
, false> > >::destroy<std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > > >(std::allocator<std::__detail::_Hash_node<std::pair<int const, st
d::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >, false> >&, std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::defa
ult_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >*) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/alloc_traits.h:497:8                                                                                               
    #14 0x249d38b in std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl
> > >, false> > >::_M_deallocate_node(std::__detail::_Hash_node<std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >, false>*) /usr/bin/../li
b/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:2102:7                                                                                                                                                                              
    #15 0x249d063 in std::_Hashtable<int, std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >, std::allocator<std::pair<int const, std::uniq
ue_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > > >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_D
efault_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_erase(unsigned long, std::__detail::_Hash_node_base*, std::__detail::_Hash_node<std::pair<int const, std::unique_ptr<node::inspector::(anon
ymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >, false>*) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable.h:1886:13                                                
    #16 0x249ca70 in std::_Hashtable<int, std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >, std::allocator<std::pair<int const, std::uniq
ue_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > > >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_D
efault_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::erase(std::__detail::_Node_const_iterator<std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::defau
lt_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >, false, false>) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable.h:1861:14                                                                                   
    #17 0x249c800 in std::_Hashtable<int, std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >, std::allocator<std::pair<int const, std::uniq
ue_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > > >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_D
efault_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::erase(std::__detail::_Node_iterator<std::pair<int const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_del
ete<node::inspector::(anonymous namespace)::ChannelImpl> > >, false, false>) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable.h:768:16                                                                                          
    #18 0x249bfa5 in std::unordered_map<int, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int 
const, std::unique_ptr<node::inspector::(anonymous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > > > >::erase(std::__detail::_Node_iterator<std::pair<int const, std::unique_ptr<node::inspector::(anonym
ous namespace)::ChannelImpl, std::default_delete<node::inspector::(anonymous namespace)::ChannelImpl> > >, false, false>) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unordered_map.h:798:21
    #19 0x24afc7f in node::inspector::NodeInspectorClient::disconnectFrontend(int) /nodejs/out/Debug/../../src/inspector_agent.cc:557:15
    #20 0x249b712 in node::inspector::(anonymous namespace)::SameThreadInspectorSession::~SameThreadInspectorSession() /nodejs/out/Debug/../../src/inspector_agent.cc:1035:13
    #21 0x249b7bb in node::inspector::(anonymous namespace)::SameThreadInspectorSession::~SameThreadInspectorSession() /nodejs/out/Debug/../../src/inspector_agent.cc:1032:59
    #22 0x24cbecf in std::default_delete<node::inspector::InspectorSession>::operator()(node::inspector::InspectorSession*) const /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unique_ptr.h:81:2
    #23 0x24c9759 in std::unique_ptr<node::inspector::InspectorSession, std::default_delete<node::inspector::InspectorSession> >::~unique_ptr() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unique_ptr.h:284:4
    #24 0x24e55a2 in node::inspector::(anonymous namespace)::JSBindingsConnection<node::inspector::(anonymous namespace)::LocalConnection>::~JSBindingsConnection() /nodejs/out/Debug/../../src/inspector_js_api.cc:63:7
    #25 0x24e55db in node::inspector::(anonymous namespace)::JSBindingsConnection<node::inspector::(anonymous namespace)::LocalConnection>::~JSBindingsConnection() /nodejs/out/Debug/../../src/inspector_js_api.cc:63:7
    #26 0x1e22c15 in node::BaseObject::DeleteMe(void*) /nodejs/out/Debug/../../src/env.cc:1138:3
    #27 0x1e1a3d4 in node::Environment::RunCleanup() /nodejs/out/Debug/../../src/env.cc:642:7
    #28 0x1d1cb46 in node::FreeEnvironment(node::Environment*) /nodejs/out/Debug/../../src/api/environment.cc:383:10
    #29 0x1c5981c in EnvironmentTestFixture::Env::~Env() /nodejs/out/Debug/../../test/cctest/node_test_fixture.h:157:7

The leak is a weak_ptr, which, from what I understand, is freed when the interrupt handler is called. With some prints it's possible to see that when the last ::Post is called (during FreeEnvironment inside ~Env), the handler is not. I think we need to somehow run all remaining handlers before exiting, or clean up the handler's data, or skip this last ::Post. Unfortunately, I don't see any V8 API to accomplish the first two suggestions.

I'm still investigating the second one, but the allocation call stack is:

Indirect leak of 384 byte(s) in 1 object(s) allocated from:
    #0 0xe0866d in operator new(unsigned long) (/nodejs/out/Debug/cctest+0xe0866d)
    #1 0x24a9e58 in __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<node::inspector::MainThreadInterface, std::allocator<node::inspector::MainThreadInterface>, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x
86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:114:27
    #2 0x24a9d63 in std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<node::inspector::MainThreadInterface, std::allocator<node::inspector::MainThreadInterface>, (__gnu_cxx::_Lock_policy)2> > >::allocate(std::allocator<std::_Sp_counted_ptr
_inplace<node::inspector::MainThreadInterface, std::allocator<node::inspector::MainThreadInterface>, (__gnu_cxx::_Lock_policy)2> >&, unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/alloc_traits.h:444:20
    #3 0x24a98a9 in std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<node::inspector::MainThreadInterface, std::allocator<node::inspector::MainThreadInterface>, (__gnu_cxx::_Lock_policy)2> > > std::__allocate_guarded<std::allocator<std::_S
p_counted_ptr_inplace<node::inspector::MainThreadInterface, std::allocator<node::inspector::MainThreadInterface>, (__gnu_cxx::_Lock_policy)2> > >(std::allocator<std::_Sp_counted_ptr_inplace<node::inspector::MainThreadInterface, std::allocator<node::inspec
tor::MainThreadInterface>, (__gnu_cxx::_Lock_policy)2> >&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/allocated_ptr.h:97:21
    #4 0x24a9629 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<node::inspector::MainThreadInterface, std::allocator<node::inspector::MainThreadInterface>, node::inspector::Agent*, uv_loop_s*, v8::Isolate*, node::MultiIsolatePlatform*>
(node::inspector::MainThreadInterface*&, std::_Sp_alloc_shared_tag<std::allocator<node::inspector::MainThreadInterface> >, node::inspector::Agent*&&, uv_loop_s*&&, v8::Isolate*&&, node::MultiIsolatePlatform*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../..
/../../include/c++/9/bits/shared_ptr_base.h:677:19
    #5 0x24a9377 in std::__shared_ptr<node::inspector::MainThreadInterface, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<node::inspector::MainThreadInterface>, node::inspector::Agent*, uv_loop_s*, v8::Isolate*, node::MultiIsolatePlatform*>(std
::_Sp_alloc_shared_tag<std::allocator<node::inspector::MainThreadInterface> >, node::inspector::Agent*&&, uv_loop_s*&&, v8::Isolate*&&, node::MultiIsolatePlatform*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:
1344:14
    #6 0x24a90b6 in std::shared_ptr<node::inspector::MainThreadInterface>::shared_ptr<std::allocator<node::inspector::MainThreadInterface>, node::inspector::Agent*, uv_loop_s*, v8::Isolate*, node::MultiIsolatePlatform*>(std::_Sp_alloc_shared_tag<std::allo
cator<node::inspector::MainThreadInterface> >, node::inspector::Agent*&&, uv_loop_s*&&, v8::Isolate*&&, node::MultiIsolatePlatform*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr.h:359:4
    #7 0x24a8de6 in std::shared_ptr<node::inspector::MainThreadInterface> std::allocate_shared<node::inspector::MainThreadInterface, std::allocator<node::inspector::MainThreadInterface>, node::inspector::Agent*, uv_loop_s*, v8::Isolate*, node::MultiIsolat
ePlatform*>(std::allocator<node::inspector::MainThreadInterface> const&, node::inspector::Agent*&&, uv_loop_s*&&, v8::Isolate*&&, node::MultiIsolatePlatform*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr.h:701:14
    #8 0x24a8af4 in std::shared_ptr<node::inspector::MainThreadInterface> std::make_shared<node::inspector::MainThreadInterface, node::inspector::Agent*, uv_loop_s*, v8::Isolate*, node::MultiIsolatePlatform*>(node::inspector::Agent*&&, uv_loop_s*&&, v8::I
solate*&&, node::MultiIsolatePlatform*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr.h:717:14
    #9 0x24a4c7f in node::inspector::NodeInspectorClient::getThreadHandle() /nodejs/out/Debug/../../src/inspector_agent.cc:674:20
    #10 0x24a8347 in node::inspector::NodeInspectorClient::getWorkerManager() /nodejs/out/Debug/../../src/inspector_agent.cc:687:43
    #11 0x24a5483 in node::inspector::NodeInspectorClient::connectFrontend(std::unique_ptr<node::inspector::InspectorSessionDelegate, std::default_delete<node::inspector::InspectorSessionDelegate> >, bool) /nodejs/out/Debug/../../src/inspector_agent.cc:54
5:59
    #12 0x2492eda in node::inspector::Agent::Connect(std::unique_ptr<node::inspector::InspectorSessionDelegate, std::default_delete<node::inspector::InspectorSessionDelegate> >, bool) /nodejs/out/Debug/../../src/inspector_agent.cc:845:29
    #13 0x24e52ee in node::inspector::(anonymous namespace)::LocalConnection::Connect(node::inspector::Agent*, std::unique_ptr<node::inspector::InspectorSessionDelegate, std::default_delete<node::inspector::InspectorSessionDelegate> >) /nodejs/out/Debug/.
./../src/inspector_js_api.cc:43:23
    #14 0x24e50f4 in node::inspector::(anonymous namespace)::JSBindingsConnection<node::inspector::(anonymous namespace)::LocalConnection>::JSBindingsConnection(node::Environment*, v8::Local<v8::Object>, v8::Local<v8::Function>) /nodejs/out/Debug/../../sr
c/inspector_js_api.cc:96:16
    #15 0x24e454a in node::inspector::(anonymous namespace)::JSBindingsConnection<node::inspector::(anonymous namespace)::LocalConnection>::New(v8::FunctionCallbackInfo<v8::Value> const&) /nodejs/out/Debug/../../src/inspector_js_api.cc:124:9
    #16 0x46a0282 in v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo) /nodejs/out/Debug/../../deps/v8/src/api/api-arguments-inl.h:158:3
    #17 0x469b9a5 in v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<true>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8:
:internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) /nodejs/out/Debug/../../deps/v8/src/builtins/builtins-api.cc:111:36
    #18 0x4699315 in v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) /nodejs/out/Debug/../../deps/v8/src/builtins/builtins-api.cc:137:5
    #19 0x46985e0 in v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) /nodejs/out/Debug/../../deps/v8/src/builtins/builtins-api.cc:129:1
    #20 0x112613f in Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit (/nodejs/out/Debug/cctest+0x112613f)
    #21 0xf14420 in Builtins_JSBuiltinsConstructStub (/nodejs/out/Debug/cctest+0xf14420)
    #22 0x1382399 in Builtins_ConstructHandler (/nodejs/out/Debug/cctest+0x1382399)
    #23 0xf23a17 in Builtins_InterpreterEntryTrampoline (/nodejs/out/Debug/cctest+0xf23a17)
    #24 0xf23a17 in Builtins_InterpreterEntryTrampoline (/nodejs/out/Debug/cctest+0xf23a17)
    #25 0xf1a9b9 in Builtins_JSEntryTrampoline (/nodejs/out/Debug/cctest+0xf1a9b9)
    #26 0xf1a797 in Builtins_JSEntry (/nodejs/out/Debug/cctest+0xf1a797)
    #27 0x350e099 in v8::internal::GeneratedCode<unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, long, unsigned long**>::Call(unsigned long, unsigned long, unsigned long, unsigned long, long, unsigned long**) /nodejs/out/Debug/.
./../deps/v8/src/execution/simulator.h:142:12
    #28 0x350e099 in v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) /nodejs/out/Debug/../../deps/v8/src/execution/execution.cc:372:33
    #29 0x350bdd8 in v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) /nodejs/out/Debug/../../deps/v8/src/execut
ion/execution.cc:466:10
    #30 0x324d433 in v8::Function::Call(v8::Local<v8::Context>, v8::Local<v8::Value>, int, v8::Local<v8::Value>*) /nodejs/out/Debug/../../deps/v8/src/api/api.cc:4922:7

Metadata

Metadata

Assignees

No one assigned

    Labels

    embeddingIssues and PRs related to embedding Node.js in another project.memoryIssues and PRs related to the memory management or memory footprint.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions