From: Konstantin Baladurin Date: Mon, 28 Aug 2017 19:02:12 +0000 (+0300) Subject: EventPipe: fix memory leaks (dotnet/coreclr#12476) X-Git-Tag: submit/tizen/20210909.063632~11030^2~6513^2~201 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d2de1e670b63b748b20c7a2a1610bedb719ae4bc;p=platform%2Fupstream%2Fdotnet%2Fruntime.git EventPipe: fix memory leaks (dotnet/coreclr#12476) Commit migrated from https://github.com/dotnet/coreclr/commit/cee0eff305d988452c589a5868bbf7dbb618aa40 --- diff --git a/src/coreclr/src/vm/eventpipebuffermanager.cpp b/src/coreclr/src/vm/eventpipebuffermanager.cpp index fa4c5e0..e7d97d5 100644 --- a/src/coreclr/src/vm/eventpipebuffermanager.cpp +++ b/src/coreclr/src/vm/eventpipebuffermanager.cpp @@ -33,6 +33,49 @@ EventPipeBufferManager::EventPipeBufferManager() #endif // _DEBUG } +EventPipeBufferManager::~EventPipeBufferManager() +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + } + CONTRACTL_END; + + if(m_pPerThreadBufferList != NULL) + { + SListElem *pElem = m_pPerThreadBufferList->GetHead(); + while(pElem != NULL) + { + SListElem *pCurElem = pElem; + + EventPipeBufferList *pThreadBufferList = pCurElem->GetValue(); + if (!pThreadBufferList->OwnedByThread()) + { + Thread *pThread = NULL; + while ((pThread = ThreadStore::GetThreadList(pThread)) != NULL) + { + if (pThread->GetEventPipeBufferList() == pThreadBufferList) + { + pThread->SetEventPipeBufferList(NULL); + break; + } + } + + // We don't delete buffers themself because they can be in-use + delete(pThreadBufferList); + } + + pElem = m_pPerThreadBufferList->GetNext(pElem); + delete(pCurElem); + } + + delete(m_pPerThreadBufferList); + m_pPerThreadBufferList = NULL; + } +} + EventPipeBuffer* EventPipeBufferManager::AllocateBufferForThread(Thread *pThread, unsigned int requestSize) { CONTRACTL @@ -436,8 +479,15 @@ void EventPipeBufferManager::DeAllocateBuffers() // In DEBUG, make sure that the element was found and removed. _ASSERTE(pElem != NULL); + + SListElem *pCurElem = pElem; + pElem = m_pPerThreadBufferList->GetNext(pElem); + delete(pCurElem); + } + else + { + pElem = m_pPerThreadBufferList->GetNext(pElem); } - pElem = m_pPerThreadBufferList->GetNext(pElem); } // Remove the list reference from the thread. @@ -483,12 +533,18 @@ void EventPipeBufferManager::DeAllocateBuffers() pElem = m_pPerThreadBufferList->FindAndRemove(pElem); _ASSERTE(pElem != NULL); + SListElem *pCurElem = pElem; + pElem = m_pPerThreadBufferList->GetNext(pElem); + delete(pCurElem); + // Now that all of the list elements have been freed, free the list itself. delete(pBufferList); pBufferList = NULL; } - - pElem = m_pPerThreadBufferList->GetNext(pElem); + else + { + pElem = m_pPerThreadBufferList->GetNext(pElem); + } } } diff --git a/src/coreclr/src/vm/eventpipebuffermanager.h b/src/coreclr/src/vm/eventpipebuffermanager.h index 23e4e7f..942d4e2 100644 --- a/src/coreclr/src/vm/eventpipebuffermanager.h +++ b/src/coreclr/src/vm/eventpipebuffermanager.h @@ -62,6 +62,7 @@ private: public: EventPipeBufferManager(); + ~EventPipeBufferManager(); // Write an event to the input thread's current event buffer. // An optional eventThread can be provided for sample profiler events. diff --git a/src/coreclr/src/vm/eventpipeconfiguration.cpp b/src/coreclr/src/vm/eventpipeconfiguration.cpp index 0a266e4..ee2c382 100644 --- a/src/coreclr/src/vm/eventpipeconfiguration.cpp +++ b/src/coreclr/src/vm/eventpipeconfiguration.cpp @@ -35,6 +35,12 @@ EventPipeConfiguration::~EventPipeConfiguration() } CONTRACTL_END; + if(m_pConfigProvider != NULL) + { + delete(m_pConfigProvider); + m_pConfigProvider = NULL; + } + if(m_pEnabledProviderList != NULL) { delete(m_pEnabledProviderList); @@ -43,6 +49,15 @@ EventPipeConfiguration::~EventPipeConfiguration() if(m_pProviderList != NULL) { + SListElem *pElem = m_pProviderList->GetHead(); + while(pElem != NULL) + { + // We don't delete provider itself because it can be in-use + SListElem *pCurElem = pElem; + pElem = m_pProviderList->GetNext(pElem); + delete(pCurElem); + } + delete(m_pProviderList); m_pProviderList = NULL; } @@ -139,6 +154,7 @@ bool EventPipeConfiguration::UnregisterProvider(EventPipeProvider &provider) { if(m_pProviderList->FindAndRemove(pElem) != NULL) { + delete(pElem); return true; } } @@ -402,9 +418,14 @@ void EventPipeConfiguration::DeleteDeferredProviders() { // The act of deleting the provider unregisters it and removes it from the list. delete(pProvider); + SListElem *pCurElem = pElem; + pElem = m_pProviderList->GetNext(pElem); + delete(pCurElem); + } + else + { + pElem = m_pProviderList->GetNext(pElem); } - - pElem = m_pProviderList->GetNext(pElem); } } diff --git a/src/coreclr/src/vm/eventpipeprovider.cpp b/src/coreclr/src/vm/eventpipeprovider.cpp index 896f9b26..f4ddd19 100644 --- a/src/coreclr/src/vm/eventpipeprovider.cpp +++ b/src/coreclr/src/vm/eventpipeprovider.cpp @@ -65,7 +65,9 @@ EventPipeProvider::~EventPipeProvider() EventPipeEvent *pEvent = pElem->GetValue(); delete pEvent; + SListElem *pCurElem = pElem; pElem = m_pEventList->GetNext(pElem); + delete pCurElem; } delete m_pEventList;