summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Robbins <brianrob@microsoft.com>2017-09-22 01:17:48 -0700
committerJan Vorlicek <janvorli@microsoft.com>2017-09-22 10:17:48 +0200
commit42309c858a742e2ec93c34fa4392a9a097d3d816 (patch)
tree5affea7a80fcc3e77d242dd5d1328f664a08f2eb
parent6cee2edabe83ebb4899c38859f6e36eb461a3759 (diff)
downloadcoreclr-42309c858a742e2ec93c34fa4392a9a097d3d816.tar.gz
coreclr-42309c858a742e2ec93c34fa4392a9a097d3d816.tar.bz2
coreclr-42309c858a742e2ec93c34fa4392a9a097d3d816.zip
Fix SIGSEGV in EventPipe on Shutdown (#14123)
* Fix a crash that occurs when a provider is registered after the configuration object has been destroyed. * Code review feedback.
-rw-r--r--src/vm/eventpipe.cpp15
-rw-r--r--src/vm/eventpipeconfiguration.cpp45
-rw-r--r--src/vm/eventpipeconfiguration.h6
-rw-r--r--src/vm/eventpipeprovider.cpp18
-rw-r--r--src/vm/eventpipeprovider.h2
5 files changed, 66 insertions, 20 deletions
diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp
index eebd2744a4..8f2e8ff937 100644
--- a/src/vm/eventpipe.cpp
+++ b/src/vm/eventpipe.cpp
@@ -390,7 +390,14 @@ EventPipeProvider* EventPipe::CreateProvider(const SString &providerName, EventP
}
CONTRACTL_END;
- return new EventPipeProvider(providerName, pCallbackFunction, pCallbackData);
+ EventPipeProvider *pProvider = NULL;
+ if (s_pConfig != NULL)
+ {
+ pProvider = s_pConfig->CreateProvider(providerName, pCallbackFunction, pCallbackData);
+ }
+
+ return pProvider;
+
}
void EventPipe::DeleteProvider(EventPipeProvider *pProvider)
@@ -418,8 +425,10 @@ void EventPipe::DeleteProvider(EventPipeProvider *pProvider)
else
{
// Delete the provider now.
- // NOTE: This will remove it from all of the EventPipe data structures.
- delete(pProvider);
+ if (s_pConfig != NULL)
+ {
+ s_pConfig->DeleteProvider(pProvider);
+ }
}
}
}
diff --git a/src/vm/eventpipeconfiguration.cpp b/src/vm/eventpipeconfiguration.cpp
index 8b703718b2..ae1dd4e099 100644
--- a/src/vm/eventpipeconfiguration.cpp
+++ b/src/vm/eventpipeconfiguration.cpp
@@ -75,7 +75,7 @@ void EventPipeConfiguration::Initialize()
CONTRACTL_END;
// Create the configuration provider.
- m_pConfigProvider = EventPipe::CreateProvider(SL(s_configurationProviderName));
+ m_pConfigProvider = CreateProvider(SL(s_configurationProviderName), NULL, NULL);
// Create the metadata event.
m_pMetadataEvent = m_pConfigProvider->AddEvent(
@@ -86,6 +86,49 @@ void EventPipeConfiguration::Initialize()
false); /* needStack */
}
+EventPipeProvider* EventPipeConfiguration::CreateProvider(const SString &providerName, EventPipeCallback pCallbackFunction, void *pCallbackData)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ // Allocate a new provider.
+ EventPipeProvider *pProvider = new EventPipeProvider(this, providerName, pCallbackFunction, pCallbackData);
+
+ // Register the provider with the configuration system.
+ RegisterProvider(*pProvider);
+
+ return pProvider;
+}
+
+void EventPipeConfiguration::DeleteProvider(EventPipeProvider *pProvider)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ PRECONDITION(pProvider != NULL);
+ }
+ CONTRACTL_END;
+
+ if (pProvider == NULL)
+ {
+ return;
+ }
+
+ // Unregister the provider.
+ UnregisterProvider(*pProvider);
+
+ // Free the provider itself.
+ delete(pProvider);
+}
+
+
bool EventPipeConfiguration::RegisterProvider(EventPipeProvider &provider)
{
CONTRACTL
diff --git a/src/vm/eventpipeconfiguration.h b/src/vm/eventpipeconfiguration.h
index 1d161367b2..baca06920a 100644
--- a/src/vm/eventpipeconfiguration.h
+++ b/src/vm/eventpipeconfiguration.h
@@ -35,6 +35,12 @@ public:
// Perform initialization that cannot be performed in the constructor.
void Initialize();
+ // Create a new provider.
+ EventPipeProvider* CreateProvider(const SString &providerName, EventPipeCallback pCallbackFunction, void *pCallbackData);
+
+ // Delete a provider.
+ void DeleteProvider(EventPipeProvider *pProvider);
+
// Register a provider.
bool RegisterProvider(EventPipeProvider &provider);
diff --git a/src/vm/eventpipeprovider.cpp b/src/vm/eventpipeprovider.cpp
index 7361541e77..c10dd33638 100644
--- a/src/vm/eventpipeprovider.cpp
+++ b/src/vm/eventpipeprovider.cpp
@@ -11,13 +11,14 @@
#ifdef FEATURE_PERFTRACING
-EventPipeProvider::EventPipeProvider(const SString &providerName, EventPipeCallback pCallbackFunction, void *pCallbackData)
+EventPipeProvider::EventPipeProvider(EventPipeConfiguration *pConfig, const SString &providerName, EventPipeCallback pCallbackFunction, void *pCallbackData)
{
CONTRACTL
{
THROWS;
GC_NOTRIGGER;
MODE_ANY;
+ PRECONDITION(pConfig != NULL);
}
CONTRACTL_END;
@@ -28,11 +29,7 @@ EventPipeProvider::EventPipeProvider(const SString &providerName, EventPipeCallb
m_pEventList = new SList<SListElem<EventPipeEvent*>>();
m_pCallbackFunction = pCallbackFunction;
m_pCallbackData = pCallbackData;
- m_pConfig = EventPipe::GetConfiguration();
- _ASSERTE(m_pConfig != NULL);
-
- // Register the provider.
- m_pConfig->RegisterProvider(*this);
+ m_pConfig = pConfig;
}
EventPipeProvider::~EventPipeProvider()
@@ -45,15 +42,6 @@ EventPipeProvider::~EventPipeProvider()
}
CONTRACTL_END;
- // Unregister the provider.
- // This call is re-entrant.
- // NOTE: We don't use the cached event pipe configuration pointer
- // in case this runs during shutdown and the configuration has already
- // been freed.
- EventPipeConfiguration* pConfig = EventPipe::GetConfiguration();
- _ASSERTE(pConfig != NULL);
- pConfig->UnregisterProvider(*this);
-
// Free all of the events.
if(m_pEventList != NULL)
{
diff --git a/src/vm/eventpipeprovider.h b/src/vm/eventpipeprovider.h
index 7b92faca72..405ce32154 100644
--- a/src/vm/eventpipeprovider.h
+++ b/src/vm/eventpipeprovider.h
@@ -64,7 +64,7 @@ private:
bool m_deleteDeferred;
// Private constructor because all providers are created through EventPipe::CreateProvider.
- EventPipeProvider(const SString &providerName, EventPipeCallback pCallbackFunction = NULL, void *pCallbackData = NULL);
+ EventPipeProvider(EventPipeConfiguration *pConfig, const SString &providerName, EventPipeCallback pCallbackFunction = NULL, void *pCallbackData = NULL);
public: