From 6bad3710478461b43d76a010d229780d4b526912 Mon Sep 17 00:00:00 2001 From: Jiri Cincura Date: Thu, 9 Jul 2026 11:34:31 +0200 Subject: [PATCH] Fix InMemoryCircularBuffer merge failure with large CircularMB When collecting with /InMemoryCircularBuffer and /CircularMB:N where N is larger than ~256, PerfView collection succeeds but the subsequent KernelTraceControl merge fails (e.g. CreateMergedTraceFile returns 0x80280012), and the requested memory grows quadratically. The buffering-mode branch of GetProperties overwrote properties->BufferSize with m_CircularBufferMB. BufferSize is a per-buffer size in KB, so a megabyte value was being written into a kilobyte field. This made each ETW buffer far larger than the OS maximum buffer size, which the relogger later chokes on during merge, and it contradicted the MinimumBuffers computation on the line above (which divides by the 64 KB quantum). It also corrupted the Attach round-trip that reconstructs buffer settings when stopping the session. Remove the erroneous assignment so BufferSize stays at the per-buffer quantum (m_BufferQuantumKB) set earlier, matching the file-based and real-time paths. MinimumBuffers alone now sizes the in-memory pool, so (MinimumBuffers * BufferSize) == m_CircularBufferMB megabytes as intended. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/TraceEvent/TraceEventSession.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/TraceEvent/TraceEventSession.cs b/src/TraceEvent/TraceEventSession.cs index 3e1cb624b..fa3d72047 100644 --- a/src/TraceEvent/TraceEventSession.cs +++ b/src/TraceEvent/TraceEventSession.cs @@ -2509,8 +2509,14 @@ private void EnsureStarted(TraceEventNativeMethods.EVENT_TRACE_PROPERTIES* prope else { properties->LogFileMode |= TraceEventNativeMethods.EVENT_TRACE_BUFFERING_MODE; + // Size the in-memory circular buffer purely by the number of buffers, leaving BufferSize at the + // per-buffer quantum set above (m_BufferQuantumKB). MinimumBuffers is intentionally computed against + // that same quantum so that (MinimumBuffers * BufferSize) == m_CircularBufferMB megabytes. + // Do NOT set BufferSize to m_CircularBufferMB here: BufferSize is a per-buffer size in KB, so treating + // a megabyte value as KB makes each buffer exceed ETW's maximum buffer size. On some systems that + // causes the subsequent KernelTraceControl merge (CreateMergedTraceFile) to fail (e.g. 0x80280012), + // and inflates the requested memory quadratically. properties->MinimumBuffers = (uint)(m_CircularBufferMB * 1024 / m_BufferQuantumKB); - properties->BufferSize = (uint)m_CircularBufferMB; } properties->LogFileNameOffset = 0; }