summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorKonstantin Baladurin <k.baladurin@partner.samsung.com>2017-08-28 22:02:12 +0300
committerBrian Robbins <brianrob@microsoft.com>2017-08-28 12:02:12 -0700
commitcee0eff305d988452c589a5868bbf7dbb618aa40 (patch)
tree94b6d4c3cc988cb3a0154c10f34292cd80b65b7c /src/vm
parentc440335be80ee0762856d0be6e91ec3ea2f90504 (diff)
downloadcoreclr-cee0eff305d988452c589a5868bbf7dbb618aa40.tar.gz
coreclr-cee0eff305d988452c589a5868bbf7dbb618aa40.tar.bz2
coreclr-cee0eff305d988452c589a5868bbf7dbb618aa40.zip
EventPipe: fix memory leaks (#12476)
Diffstat (limited to 'src/vm')
-rw-r--r--src/vm/eventpipebuffermanager.cpp62
-rw-r--r--src/vm/eventpipebuffermanager.h1
-rw-r--r--src/vm/eventpipeconfiguration.cpp25
-rw-r--r--src/vm/eventpipeprovider.cpp2
4 files changed, 85 insertions, 5 deletions
diff --git a/src/vm/eventpipebuffermanager.cpp b/src/vm/eventpipebuffermanager.cpp
index fa4c5e0b68..e7d97d5732 100644
--- a/src/vm/eventpipebuffermanager.cpp
+++ b/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<EventPipeBufferList*> *pElem = m_pPerThreadBufferList->GetHead();
+ while(pElem != NULL)
+ {
+ SListElem<EventPipeBufferList*> *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<EventPipeBufferList*> *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<EventPipeBufferList*> *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/vm/eventpipebuffermanager.h b/src/vm/eventpipebuffermanager.h
index 23e4e7f3e9..942d4e2242 100644
--- a/src/vm/eventpipebuffermanager.h
+++ b/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/vm/eventpipeconfiguration.cpp b/src/vm/eventpipeconfiguration.cpp
index 0a266e4849..ee2c3820bf 100644
--- a/src/vm/eventpipeconfiguration.cpp
+++ b/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<EventPipeProvider*> *pElem = m_pProviderList->GetHead();
+ while(pElem != NULL)
+ {
+ // We don't delete provider itself because it can be in-use
+ SListElem<EventPipeProvider*> *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<EventPipeProvider*> *pCurElem = pElem;
+ pElem = m_pProviderList->GetNext(pElem);
+ delete(pCurElem);
+ }
+ else
+ {
+ pElem = m_pProviderList->GetNext(pElem);
}
-
- pElem = m_pProviderList->GetNext(pElem);
}
}
diff --git a/src/vm/eventpipeprovider.cpp b/src/vm/eventpipeprovider.cpp
index 896f9b2650..f4ddd19b78 100644
--- a/src/vm/eventpipeprovider.cpp
+++ b/src/vm/eventpipeprovider.cpp
@@ -65,7 +65,9 @@ EventPipeProvider::~EventPipeProvider()
EventPipeEvent *pEvent = pElem->GetValue();
delete pEvent;
+ SListElem<EventPipeEvent*> *pCurElem = pElem;
pElem = m_pEventList->GetNext(pElem);
+ delete pCurElem;
}
delete m_pEventList;