diff --git a/src/Draco.Compiler.Fuzzer/TuiTracer.cs b/src/Draco.Compiler.Fuzzer/TuiTracer.cs index 32a11cb12..88b07f00d 100644 --- a/src/Draco.Compiler.Fuzzer/TuiTracer.cs +++ b/src/Draco.Compiler.Fuzzer/TuiTracer.cs @@ -351,7 +351,7 @@ public void InputFuzzStarted(SyntaxTree input, TargetInfo targetInfo) this.fuzzStarts.Add(targetInfo.Id, this.stopwatch.Elapsed); } - public void InputFuzzed(SyntaxTree input, TargetInfo targetInfo, CoverageResult coverageResult) + public void InputFuzzEnded(SyntaxTree input, TargetInfo targetInfo, CoverageResult coverageResult) { // Counters ++this.fuzzedInputCounter; diff --git a/src/Draco.Fuzzing/Fuzzer.cs b/src/Draco.Fuzzing/Fuzzer.cs index 622d851fa..b097af311 100644 --- a/src/Draco.Fuzzing/Fuzzer.cs +++ b/src/Draco.Fuzzing/Fuzzer.cs @@ -202,7 +202,7 @@ private ExecutionResult GetExecutionResult(QueueEntry entry) lock (this.tracerSync) this.Tracer.InputFaulted(input, faultResult); } var coverage = this.CoverageReader.Read(targetInfo); - lock (this.tracerSync) this.Tracer.InputFuzzed(input, targetInfo, coverage); + lock (this.tracerSync) this.Tracer.InputFuzzEnded(input, targetInfo, coverage); var compressedCoverage = this.CoverageCompressor.Compress(coverage); var isInteresting = this.IsInteresting(compressedCoverage); var executionResult = new ExecutionResult(compressedCoverage, faultResult); diff --git a/src/Draco.Fuzzing/ITracer.cs b/src/Draco.Fuzzing/ITracer.cs index 10c524cce..5c41d05e2 100644 --- a/src/Draco.Fuzzing/ITracer.cs +++ b/src/Draco.Fuzzing/ITracer.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Draco.Coverage; namespace Draco.Fuzzing; @@ -34,7 +35,7 @@ public interface ITracer /// The input that was fuzzed. /// The target information. /// The coverage of the input. - public void InputFuzzed(TInput input, TargetInfo targetInfo, CoverageResult coverageResult); + public void InputFuzzEnded(TInput input, TargetInfo targetInfo, CoverageResult coverageResult); /// /// Called when a smaller input was found. @@ -86,10 +87,65 @@ private NullTracer() public void InputsEnqueued(IEnumerable inputs) { } public void InputDequeued(T input) { } public void InputFuzzStarted(T input, TargetInfo targetInfo) { } - public void InputFuzzed(T input, TargetInfo targetInfo, CoverageResult coverageResult) { } + public void InputFuzzEnded(T input, TargetInfo targetInfo, CoverageResult coverageResult) { } public void MinimizationFound(T input, T minimizedInput) { } public void MutationFound(T input, T mutatedInput) { } public void InputFaulted(T input, FaultResult fault) { } public void FuzzerStarted() { } public void FuzzerFinished() { } } + +/// +/// A tracer that broadcasts to multiple tracers. +/// +/// The type of the input data. +/// The tracers to broadcast to. +public sealed class BroadcastTracer(IEnumerable> tracers) : ITracer +{ + private readonly List> tracers = tracers.ToList(); + + public void InputsEnqueued(IEnumerable inputs) + { + foreach (var tracer in this.tracers) tracer.InputsEnqueued(inputs); + } + + public void InputDequeued(T input) + { + foreach (var tracer in this.tracers) tracer.InputDequeued(input); + } + + public void InputFuzzStarted(T input, TargetInfo targetInfo) + { + foreach (var tracer in this.tracers) tracer.InputFuzzStarted(input, targetInfo); + } + + public void InputFuzzEnded(T input, TargetInfo targetInfo, CoverageResult coverageResult) + { + foreach (var tracer in this.tracers) tracer.InputFuzzEnded(input, targetInfo, coverageResult); + } + + public void MinimizationFound(T input, T minimizedInput) + { + foreach (var tracer in this.tracers) tracer.MinimizationFound(input, minimizedInput); + } + + public void MutationFound(T input, T mutatedInput) + { + foreach (var tracer in this.tracers) tracer.MutationFound(input, mutatedInput); + } + + public void InputFaulted(T input, FaultResult fault) + { + foreach (var tracer in this.tracers) tracer.InputFaulted(input, fault); + } + + public void FuzzerStarted() + { + foreach (var tracer in this.tracers) tracer.FuzzerStarted(); + } + + public void FuzzerFinished() + { + foreach (var tracer in this.tracers) tracer.FuzzerFinished(); + } +}