New issue
Advanced search Search tips

Issue 749115 link

Starred by 2 users

Issue metadata

Status: Fixed
Owner:
Closed: Sep 2017
Cc:
EstimatedDays: ----
NextAction: ----
OS: Linux
Pri: 3
Type: Bug



Sign in to add a comment

Potential memory leak with DiscardableSharedMemoryManager

Project Member Reported by etienneb@chromium.org, Jul 26 2017

Issue description

I ran the extension provided in:
  https://bugs.chromium.org/p/chromium/issues/detail?id=707136

which basically 
  1) open tab
  2) navigate to google.com
  3) close tab
  4) repeat

After a day, the browser process was using 1.3G of memory.

The browser is running with native heap profiling activated.
By looking to a memory dump, we can determine that there is 11M objects still alive allocated with the stackframe provided as attachment.
 
tasks.png
39.9 KB View Download
bug.png
206 KB View Download
The leak is only happening on a debug build only (not official builds).

Code gated by 'DCHECK_IS_ON()' is incorrect. SEE:
https://cs.chromium.org/chromium/src/base/memory/discardable_shared_memory.cc?l=184&rcl=46a392696be217f10cbe1864f3173df5651bc301


The bug can be triggered by adding a DCHECK as the first statement in 
bool DiscardableSharedMemory::Unmap() {
  DCHECK_EQ(0U, locked_page_count_);    <<<<-----


Turned out, Unmap can be called and pages are unmapped (not unlocked).
But the debugging code is keeping track of them in a set. This set is
growing up over time.

#0 0x7f95011e07cd base::debug::StackTrace::StackTrace()
#1 0x7f95011deb9c base::debug::StackTrace::StackTrace()
#2 0x7f950126f17a logging::LogMessage::~LogMessage()
#3 0x7f950127854d base::DiscardableSharedMemory::Unmap()
#4 0x7f94e6f1f07c discardable_memory::DiscardableSharedMemoryManager::ReleaseMemory()
#5 0x7f94e6f1ee1b discardable_memory::DiscardableSharedMemoryManager::ClientRemoved()
#6 0x7f94e6f20441 discardable_memory::(anonymous namespace)::MojoDiscardableSharedMemoryManagerImpl::~MojoDiscardableSharedMemoryManagerImpl()
#7 0x7f94e6f20479 discardable_memory::(anonymous namespace)::MojoDiscardableSharedMemoryManagerImpl::~MojoDiscardableSharedMemoryManagerImpl()
#8 0x7f94e6f2cb64 mojo::StrongBinding<>::~StrongBinding()
#9 0x7f94e6f2ca27 mojo::StrongBinding<>::Close()
#10 0x7f94e6f2b245 mojo::StrongBinding<>::OnConnectionError()
#11 0x7f94e6f2c6ef _ZN4base8internal13FunctorTraitsIMN4mojo13StrongBindingIN18discardable_memory5mojom30DiscardableSharedMemoryManagerEEEFvjRKNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEEvE6InvokeIPS7_JjSG_EEEvSI_OT_DpOT0_
#12 0x7f94e6f2c61a _ZN4base8internal12InvokeHelperILb0EvE8MakeItSoIRKMN4mojo13StrongBindingIN18discardable_memory5mojom30DiscardableSharedMemoryManagerEEEFvjRKNSt3__112basic_stringIcNSA_11char_traitsIcEENSA_9allocatorIcEEEEEJPS9_jSI_EEEvOT_DpOT0_
#13 0x7f94e6f2c595 _ZN4base8internal7InvokerINS0_9BindStateIMN4mojo13StrongBindingIN18discardable_memory5mojom30DiscardableSharedMemoryManagerEEEFvjRKNSt3__112basic_stringIcNS9_11char_traitsIcEENS9_9allocatorIcEEEEEJNS0_17UnretainedWrapperIS8_EEEEEFvjSH_EE7RunImplIRKSJ_RKNS9_5tupleIJSL_EEEJLm0EEEEvOT_OT0_NS_13IndexSequenceIJXspT1_EEEEOjSH_
#14 0x7f94e6f2c4c4 _ZN4base8internal7InvokerINS0_9BindStateIMN4mojo13StrongBindingIN18discardable_memory5mojom30DiscardableSharedMemoryManagerEEEFvjRKNSt3__112basic_stringIcNS9_11char_traitsIcEENS9_9allocatorIcEEEEEJNS0_17UnretainedWrapperIS8_EEEEEFvjSH_EE3RunEPNS0_13BindStateBaseEOjSH_
#15 0x7f94ff8ba210 _ZNO4base8CallbackIFvjRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEELNS_8internal8CopyModeE0ELNSB_10RepeatModeE0EE3RunEjS9_
#16 0x7f94ff8b8cb7 mojo::InterfaceEndpointClient::NotifyError()
#17 0x7f94ff8d2325 mojo::internal::MultiplexRouter::ProcessNotifyErrorTask()
#18 0x7f94ff8cef8f mojo::internal::MultiplexRouter::ProcessTasks()
#19 0x7f94ff8ccf2d mojo::internal::MultiplexRouter::OnPipeConnectionError()
#20 0x7f94ff8b1f1d _ZN4base8internal13FunctorTraitsIMN4mojo8internal19ControlMessageProxyEFvvEvE6InvokeIPS4_JEEEvS6_OT_DpOT0_
#21 0x7f94ff8b1e64 _ZN4base8internal12InvokeHelperILb0EvE8MakeItSoIRKMN4mojo8internal19ControlMessageProxyEFvvEJPS6_EEEvOT_DpOT0_
#22 0x7f94ff8d89a5 _ZN4base8internal7InvokerINS0_9BindStateIMN4mojo8internal15MultiplexRouterEFvvEJNS0_17UnretainedWrapperIS5_EEEEEFvvEE7RunImplIRKS7_RKNSt3__15tupleIJS9_EEEJLm0EEEEvOT_OT0_NS_13IndexSequenceIJXspT1_EEEE
#23 0x7f94ff8d88ec _ZN4base8internal7InvokerINS0_9BindStateIMN4mojo8internal15MultiplexRouterEFvvEJNS0_17UnretainedWrapperIS5_EEEEEFvvEE3RunEPNS0_13BindStateBaseE
#24 0x7f94ff8a8f71 _ZNO4base8CallbackIFvvELNS_8internal8CopyModeE0ELNS2_10RepeatModeE0EE3RunEv
#25 0x7f94ff8a63aa mojo::Connector::HandleError()
#26 0x7f94ff8a79cd mojo::Connector::OnHandleReadyInternal()
#27 0x7f94ff8a78bb mojo::Connector::OnWatcherHandleReady()
#28 0x7f94ff8ab17f _ZN4base8internal13FunctorTraitsIMN4mojo9ConnectorEFvjEvE6InvokeIPS3_JjEEEvS5_OT_DpOT0_
#29 0x7f94ff8ab0af _ZN4base8internal12InvokeHelperILb0EvE8MakeItSoIRKMN4mojo9ConnectorEFvjEJPS5_jEEEvOT_DpOT0_
#30 0x7f94ff8ab045 _ZN4base8internal7InvokerINS0_9BindStateIMN4mojo9ConnectorEFvjEJNS0_17UnretainedWrapperIS4_EEEEEFvjEE7RunImplIRKS6_RKNSt3__15tupleIJS8_EEEJLm0EEEEvOT_OT0_NS_13IndexSequenceIJXspT1_EEEEOj
#31 0x7f94ff8aaf84 _ZN4base8internal7InvokerINS0_9BindStateIMN4mojo9ConnectorEFvjEJNS0_17UnretainedWrapperIS4_EEEEEFvjEE3RunEPNS0_13BindStateBaseEOj
#32 0x7f94ff8a184c _ZNKR4base8CallbackIFvjELNS_8internal8CopyModeE1ELNS2_10RepeatModeE1EE3RunEj
#33 0x7f94ff8aa11f mojo::SimpleWatcher::DiscardReadyState()
#34 0x7f94ff8aa394 _ZN4base8internal13FunctorTraitsIPFvRKNS_8CallbackIFvjELNS0_8CopyModeE1ELNS0_10RepeatModeE1EEEjRKN4mojo18HandleSignalsStateEEvE6InvokeIJS8_jSC_EEEvSE_DpOT_
#35 0x7f94ff8aa340 _ZN4base8internal12InvokeHelperILb0EvE8MakeItSoIRKPFvRKNS_8CallbackIFvjELNS0_8CopyModeE1ELNS0_10RepeatModeE1EEEjRKN4mojo18HandleSignalsStateEEJSA_jSE_EEEvOT_DpOT0_
#36 0x7f94ff8aa2e0 _ZN4base8internal7InvokerINS0_9BindStateIPFvRKNS_8CallbackIFvjELNS0_8CopyModeE1ELNS0_10RepeatModeE1EEEjRKN4mojo18HandleSignalsStateEEJS7_EEEFvjSD_EE7RunImplIRKSF_RKNSt3__15tupleIJS7_EEEJLm0EEEEvOT_OT0_NS_13IndexSequenceIJXspT1_EEEEOjSD_
#37 0x7f94ff8aa214 _ZN4base8internal7InvokerINS0_9BindStateIPFvRKNS_8CallbackIFvjELNS0_8CopyModeE1ELNS0_10RepeatModeE1EEEjRKN4mojo18HandleSignalsStateEEJS7_EEEFvjSD_EE3RunEPNS0_13BindStateBaseEOjSD_
#38 0x7f94ff85a7ac _ZNKR4base8CallbackIFvjRKN4mojo18HandleSignalsStateEELNS_8internal8CopyModeE1ELNS6_10RepeatModeE1EE3RunEjS4_
#39 0x7f94ff859d65 mojo::SimpleWatcher::OnHandleReady()
#40 0x7f94ff85a976 mojo::SimpleWatcher::Context::Notify()
#41 0x7f94ff859fb9 mojo::SimpleWatcher::Context::CallNotify()
#42 0x7f94f7045e21 mojo::edk::WatcherDispatcher::InvokeWatchCallback()
#43 0x7f94f7044ff7 mojo::edk::Watch::InvokeCallback()
#44 0x7f94f7038239 mojo::edk::RequestContext::~RequestContext()
#45 0x7f94f70012fe mojo::edk::NodeChannel::OnChannelError()
#46 0x7f94f6fc1199 mojo::edk::Channel::OnError()
#47 0x7f94f6fc6c88 mojo::edk::(anonymous namespace)::ChannelPosix::OnFileCanReadWithoutBlocking()
#48 0x7f95012a7191 base::MessagePumpLibevent::FileDescriptorWatcher::OnFileCanReadWithoutBlocking()
#49 0x7f95012a8959 base::MessagePumpLibevent::OnLibeventNotification()
#50 0x7f950156ddde event_process_active
#51 0x7f950156d427 event_base_loop
#52 0x7f95012a8d86 base::MessagePumpLibevent::Run()
#53 0x7f950129d834 base::MessageLoop::Run()
#54 0x7f95013524bd base::RunLoop::Run()
#55 0x7f950141e184 base::Thread::Run()
#56 0x7f94fab43a36 content::BrowserThreadImpl::IOThreadRun()
#57 0x7f94fab43d3b content::BrowserThreadImpl::Run()
#58 0x7f950141eda2 base::Thread::ThreadMain()
#59 0x7f95013fff11 base::(anonymous namespace)::ThreadFunc()
#60 0x7f950183e184 start_thread
#61 0x7f94eb3b7ffd clone


The bug was introduced here:
  https://codereview.chromium.org/809603004
Owner: etienneb@chromium.org
Status: Started (was: Untriaged)
Project Member

Comment 5 by bugdroid1@chromium.org, Aug 7 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/8ae3ea1c2efcf9d2786cb1af66315b08f0a95051

commit 8ae3ea1c2efcf9d2786cb1af66315b08f0a95051
Author: Etienne Bergeron <etienneb@chromium.org>
Date: Mon Aug 07 18:50:33 2017

Fix memory leak with shared discardable memory tracking.

The set |locked_pages_| is improperly updated on a Unmap.
Locked pages are released and should not be kept in the set.

The counter |locked_page_count_| was also incorrectly updated.
But, it was in-sync with the size of |locked_pages_|.

The bug was introduced here:
  https://codereview.chromium.org/809603004

See crbug/749115 for more details.

R=danakj@chromium.org

Bug:  749115 
Change-Id: I825ef3b03ca6fd4b91588fcb882013baac51a1db
Reviewed-on: https://chromium-review.googlesource.com/587970
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Erik Chen <erikchen@chromium.org>
Commit-Queue: Etienne Bergeron <etienneb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#492372}
[modify] https://crrev.com/8ae3ea1c2efcf9d2786cb1af66315b08f0a95051/base/memory/discardable_shared_memory.cc
[modify] https://crrev.com/8ae3ea1c2efcf9d2786cb1af66315b08f0a95051/base/memory/discardable_shared_memory.h

Status: Fixed (was: Started)

Sign in to add a comment