{"record":{"id":"51db5d98bea861e8","repo":"dotnet/BenchmarkDotNet","slug":"one-workload-iteration-stop-event-is-missing-unab","errorCode":null,"errorMessage":"One workload iteration stop event is missing, unable to calculate stats","messagePattern":"One workload iteration stop event is missing, unable to calculate stats","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/BenchmarkDotNet.Diagnostics.Windows/Tracing/TraceLogParser.cs","lineNumber":126,"sourceCode":"            {\n                if (!totalOperationsPerIteration.HasValue)\n                    totalOperationsPerIteration = totalOperations;\n                else if (totalOperationsPerIteration.Value != totalOperations)\n                    throw new InvalidOperationException($\"TotalOperations count can't change during the benchmark run! Invalid trace!\");\n\n                workloadTimestamps.Add(timeStamp);\n            }\n        }\n\n        public void HandleNewSample(double timeStamp, ulong instructionPointer, int profileSourceId)\n            => samples.Add((timeStamp, instructionPointer, profileSourceId));\n\n        public IEnumerable<Metric> CalculateMetrics(Dictionary<int, int> profileSourceIdToInterval, PreciseMachineCounter[] counters)\n        {\n            if (overheadTimestamps.Count % 2 != 0)\n                throw new InvalidOperationException(\"One overhead iteration stop event is missing, unable to calculate stats\");\n            if (workloadTimestamps.Count % 2 != 0)\n                throw new InvalidOperationException(\"One workload iteration stop event is missing, unable to calculate stats\");\n            if (!totalOperationsPerIteration.HasValue)\n                throw new InvalidOperationException(\"TotalOperations is missing, unable to calculate stats\");\n\n            var overheadIterations = CreateIterationData(overheadTimestamps);\n            var workloadIterations = CreateIterationData(workloadTimestamps);\n\n            SumCountersPerIterations(profileSourceIdToInterval, workloadIterations, overheadIterations, counters);\n\n            var workloadTotalPerCounter = Sum(workloadIterations);\n            var overheadTotalPerCounter = Sum(overheadIterations);\n\n            return workloadTotalPerCounter.Select(perCounter =>\n            {\n                var pmc = counters.Single(counter => counter.ProfileSourceId == perCounter.Key);\n\n                overheadTotalPerCounter.TryGetValue(perCounter.Key, out var overhead);\n\n                // result = (avg(workload) - avg(overhead))/op","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/dotnet/BenchmarkDotNet/blob/b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3/src/BenchmarkDotNet.Diagnostics.Windows/Tracing/TraceLogParser.cs#L108-L144","documentation":"Symmetric to the overhead check: CalculateMetrics throws when workloadTimestamps.Count is odd, i.e. a WorkloadActualStart had no matching WorkloadActualStop. Without complete workload iteration boundaries the PMC counter samples cannot be attributed to iterations.","triggerScenarios":"An ETW WorkloadActualStop event is missing from the trace. Same root causes as the overhead variant: dropped events, process exit mid-iteration, partial capture, or an exception that aborted the workload before the stop event fired.","commonSituations":"Benchmark threw an unhandled exception inside a workload iteration; ETW buffer overflow on a noisy machine; the trace was started/stopped asynchronously and missed the final stop event.","solutions":["Make sure the benchmark method does not throw so the engine can emit the stop event.","Raise ETW buffer size and number of buffers when collecting the .etl.","Re-run in isolation; intermittent event loss is environment-dependent."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { /* run + parse trace */ }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"workload iteration stop event is missing\"))\n{\n    log.Warning(\"ETW dropped a workload stop event; rerun with larger buffers / in isolation.\");\n}","preventionTips":["Make the benchmark method not throw so the engine emits WorkloadActualStop.","Raise ETW buffer size/count on noisy machines.","Capture the full run window; avoid partial traces."],"tags":["benchmarkdotnet","windows","etw","pmc","tracing","trace-corruption"],"backgroundTag":null,"analyzedSha":"b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3","analyzedAt":"2026-08-13T19:12:24.196Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}