BenchmarkDotNet
BenchmarkDotNet copied to clipboard
[Bug] `InvalidOperationException` thrown on some conditions when using `BenchmarkDotNetDiagnosers`
When running BenchmarkDotNet.Samples project with following command.
dotnet run -c Release --framework net8.0 --anyCategories Dummy
benchmark project throws following exception.
Unhandled exception. System.InvalidOperationException: Tool CPUUsageTool is already added.
Stacktrace
Unhandled exception. System.InvalidOperationException: Tool CPUUsageTool is already added.
at Microsoft.VSDiagnostics.VSDiagnosticsDiagnoser..ctor(IDiagnosticsTool tool, String outputFileName, Boolean openDiagsessionInVS, Func`2 validationFunction)
at Microsoft.VSDiagnostics.VSDiagnosticsToolAttribute.get_Config()
at Microsoft.VSDiagnostics.CPUUsageDiagnoserAttribute.get_Config()
at BenchmarkDotNet.Running.BenchmarkConverter.GetFullTypeConfig(Type type, IConfig config) in C:\Projects\GitHub\thirdparty\BenchmarkDotNet\src\BenchmarkDotNet\Running\BenchmarkConverter.cs:line 94
at BenchmarkDotNet.Running.BenchmarkConverter.MethodsToBenchmarksWithFullConfig(Type type, MethodInfo[] benchmarkMethods, IConfig config) in C:\Projects\GitHub\thirdparty\BenchmarkDotNet\src\BenchmarkDotNet\Running\BenchmarkConverter.cs:line 46
at BenchmarkDotNet.Running.BenchmarkConverter.TypeToBenchmarks(Type type, IConfig config) in C:\Projects\GitHub\thirdparty\BenchmarkDotNet\src\BenchmarkDotNet\Running\BenchmarkConverter.cs:line 29
at BenchmarkDotNet.Running.TypeFilter.<>c__DisplayClass1_0.<Filter>b__0(Type type) in C:\Projects\GitHub\thirdparty\BenchmarkDotNet\src\BenchmarkDotNet\Running\TypeFilter.cs:line 68
at System.Linq.Enumerable.SelectListIterator`2.MoveNext()
at System.Linq.Enumerable.WhereEnumerableIterator`1.ToArray()
at BenchmarkDotNet.Running.TypeFilter.Filter(IConfig effectiveConfig, IEnumerable`1 types) in C:\Projects\GitHub\thirdparty\BenchmarkDotNet\src\BenchmarkDotNet\Running\TypeFilter.cs:line 67
at BenchmarkDotNet.ConsoleArguments.CorrectionsSuggester..ctor(IReadOnlyList`1 types) in C:\Projects\GitHub\thirdparty\BenchmarkDotNet\src\BenchmarkDotNet\ConsoleArguments\CorrectionsSuggester.cs:line 20
at BenchmarkDotNet.Running.UserInteraction.PrintWrongFilterInfo(IReadOnlyList`1 allTypes, ILogger logger, String[] userFilters) in C:\Projects\GitHub\thirdparty\BenchmarkDotNet\src\BenchmarkDotNet\Running\UserInteraction.cs:line 57
at BenchmarkDotNet.Running.BenchmarkSwitcher.RunWithDirtyAssemblyResolveHelper(String[] args, IConfig config, Boolean askUserForInput) in C:\Projects\GitHub\thirdparty\BenchmarkDotNet\src\BenchmarkDotNet\Running\BenchmarkSwitcher.cs:line 138
at BenchmarkDotNet.Running.BenchmarkSwitcher.Run(String[] args, IConfig config) in C:\Projects\GitHub\thirdparty\BenchmarkDotNet\src\BenchmarkDotNet\Running\BenchmarkSwitcher.cs:line 84
at BenchmarkDotNet.Samples.Program.Main(String[] args) in C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\Program.cs:line 7
Background
When specified benchmark category is not found.
BenchmarkDotNet try to call PrintWrongFilterInfo with CorrectionsSuggester.cs.
And it internally call VSDiagnosticsDiagnoser's ctor and throw exceptions.
Same issue can be reproduced when specifying [CPUUsageDiagnoser] attribute on multiple benchmarks.
And it can also happens with multiple constructor calls.
var diagnoser1 = new CPUUsageDiagnoser(cpuSampleRate: 0);
var diagnoser2 = new CPUUsageDiagnoser(cpuSampleRate: 50);
I thought it seems to be fixed on [Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers] side.