If IPC connections fails, then remove active session. (#24082)
authorJosé Rivero <jorive@microsoft.com>
Thu, 18 Apr 2019 20:18:26 +0000 (13:18 -0700)
committerGitHub <noreply@github.com>
Thu, 18 Apr 2019 20:18:26 +0000 (13:18 -0700)
src/vm/eventpipe.cpp
src/vm/eventpipe.h
src/vm/eventpipefile.cpp
src/vm/eventpipefile.h
src/vm/fastserializer.cpp
src/vm/fastserializer.h

index dc94c2b..b6ec530 100644 (file)
@@ -351,6 +351,19 @@ void EventPipe::Disable(EventPipeSessionID id)
 
     // Take the lock before disabling tracing.
     CrstHolder _crst(GetLock());
+    DisableInternal(reinterpret_cast<EventPipeSessionID>(s_pSession));
+}
+
+void EventPipe::DisableInternal(EventPipeSessionID id)
+{
+    CONTRACTL
+    {
+        THROWS;
+        GC_TRIGGERS;
+        MODE_ANY;
+        PRECONDITION(GetLock()->OwnedByCurrentThread());
+    }
+    CONTRACTL_END;
 
     if (s_pConfig != NULL && s_pConfig->Enabled())
     {
@@ -503,6 +516,8 @@ void WINAPI EventPipe::FlushTimer(PVOID parameter, BOOLEAN timerFired)
     }
     CONTRACTL_END;
 
+    GCX_PREEMP();
+
     // Take the lock control lock to make sure that tracing isn't disabled during this operation.
     CrstHolder _crst(GetLock());
 
@@ -513,8 +528,6 @@ void WINAPI EventPipe::FlushTimer(PVOID parameter, BOOLEAN timerFired)
     if (!Enabled() || s_pSession->GetSessionType() != EventPipeSessionType::IpcStream)
         return;
 
-    GCX_PREEMP();
-
     if (CLRGetTickCount64() > (s_lastFlushSwitchTime + 100))
     {
         // Get the current time stamp.
@@ -526,6 +539,16 @@ void WINAPI EventPipe::FlushTimer(PVOID parameter, BOOLEAN timerFired)
 
         s_lastFlushSwitchTime = CLRGetTickCount64();
     }
+
+    if (s_pFile->HasErrors())
+    {
+        EX_TRY
+        {
+            DisableInternal(reinterpret_cast<EventPipeSessionID>(s_pSession));
+        }
+        EX_CATCH {}
+        EX_END_CATCH(SwallowAllExceptions);
+    }
 }
 
 EventPipeSession *EventPipe::GetSession(EventPipeSessionID id)
index e3704d7..b40a0b7 100644 (file)
@@ -305,6 +305,8 @@ private:
     // The counterpart to WriteEvent which after the payload is constructed
     static void WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload &payload, LPCGUID pActivityId = NULL, LPCGUID pRelatedActivityId = NULL);
 
+    static void DisableInternal(EventPipeSessionID id);
+
     // Enable the specified EventPipe session.
     static EventPipeSessionID Enable(
         LPCWSTR strOutputPath,
index b2d82e5..ee16767 100644 (file)
@@ -66,6 +66,12 @@ EventPipeFile::~EventPipeFile()
     delete m_pSerializer;
 }
 
+bool EventPipeFile::HasErrors() const
+{
+    LIMITED_METHOD_CONTRACT;
+    return (m_pSerializer == nullptr) || m_pSerializer->HasWriteErrors();
+}
+
 void EventPipeFile::WriteEvent(EventPipeEventInstance &instance)
 {
     CONTRACTL
index 9441ec4..00e32ae 100644 (file)
@@ -22,6 +22,7 @@ public:
 
     void WriteEvent(EventPipeEventInstance &instance);
     void Flush();
+    bool HasErrors() const;
 
     const char *GetTypeName() override
     {
index 620b510..5457ee9 100644 (file)
@@ -188,7 +188,7 @@ void FastSerializer::WriteBuffer(BYTE *pBuffer, unsigned int length)
     EX_TRY
     {
         uint32_t outCount;
-        m_pStreamWriter->Write(pBuffer, length, outCount);
+        bool fSuccess = m_pStreamWriter->Write(pBuffer, length, outCount);
 
 #ifdef _DEBUG
         size_t prevPos = m_currentPos;
@@ -198,7 +198,7 @@ void FastSerializer::WriteBuffer(BYTE *pBuffer, unsigned int length)
         // This will cause us to stop writing to the file.
         // The file will still remain open until shutdown so that we don't
         // have to take a lock at this level when we touch the file stream.
-        m_writeErrorEncountered = (length != outCount);
+        m_writeErrorEncountered = (length != outCount) || !fSuccess;
 
 #ifdef _DEBUG
         _ASSERTE(m_writeErrorEncountered || (prevPos < m_currentPos));
index 2c669f0..f62bb62 100644 (file)
@@ -62,7 +62,7 @@ private:
 };
 
 //!
-//! Implements a StreamWriter for writing bytes to an File.
+//! Implements a StreamWriter for writing bytes to a File.
 //!
 class FileStreamWriter final : public StreamWriter
 {