How do I read the EK9 fuzz HTML dashboard?

← Fuzzing and Mutation Testing · Ref: Q752

The -fuzz6 flag generates an interactive HTML dashboard at fuzz-report/index.html with four key sections.

ERROR CODE HEATMAP

A colour-coded matrix of every compiler error code triggered during fuzzing. Brighter cells mean more frequent triggers. Error codes that never appear reveal gaps in the fuzzer's grammar coverage.

PHASE DISTRIBUTION

A bar chart showing how many generated files reached each compilation phase (PARSING, SYMBOL_DEFINITION, TYPE_HIERARCHY_CHECKS, PRE_IR_CHECKS, etc.). A healthy fuzzer produces files that exercise all phases, not just the parser.

THROUGHPUT CURVE

A time-series graph of iterations per second. Drops in throughput indicate complex generated files that take longer to compile. Sustained low throughput may reveal compiler performance issues.

CRASH SUMMARY

A table listing each unique crash with: error message, stack trace hash, affected phase, and link to the minimal reproduction file in ./fuzz-crashes/.

READING THE DASHBOARD

- All error codes triggered = good fuzzer coverage.
- Files reaching deep phases = grammar generator working well.
- Zero crashes after long runs = compiler is robust.
- Surviving error code gaps = improve generator for those constructs.

See Q749 for fuzzing overview. See Q751 for output formats. See Q627 for profiling dashboard (similar HTML pattern). See Q321 for quality report dashboard.

Example

defines module qa.fuzzingandmutation.htmldashboard

  <?-
    Code with multiple error paths that produce
    a rich distribution in the fuzz heatmap.
    Different branches exercise different compiler
    phases and error detection logic.
  -?>

  defines trait

    Measurable
      measurement() as pure
        <- rtn as Float: 0.0

      label() as pure
        <- rtn as String: String()

  defines class

    Sensor as open
      sensorName as String: String()
      currentReading as Float: 0.0

      Sensor()
        ->
          initialName as String
        this.sensorName :=? initialName

      reading() as pure
        <- rtn as Float: this.currentReading

      updateReading()
        -> newReading as Float
        this.currentReading: newReading

      operator $ as pure
        <- rtn as String: `${this.sensorName}: ${this.currentReading}`

      default operator ?

  defines function

    summariseSensors()
      -> sensors as List of Sensor
      <- summary as String: "No sensors"

      count <- length sensors
      zero <- 0
      if count > zero
        total <- 0.0
        for sensor in sensors
          total: total + sensor.reading()
        avg <- total / #^count
        summary: `${count} sensors, avg ${avg}`

  defines program

    FuzzHtmlDashboardDemo()
      stdout <- Stdout()

      alpha <- Sensor("alpha")
      beta <- Sensor("beta")
      gamma <- Sensor("gamma")

      alpha.updateReading(23.5)
      beta.updateReading(19.8)
      gamma.updateReading(27.1)

      sensors <- [alpha, beta, gamma]
      for sensor in sensors
        stdout.println($sensor)

      stdout.println(summariseSensors(sensors))
Other ways to ask this
  • What does the fuzz-report/index.html show?
  • How do I interpret EK9 fuzz statistics?
  • What are error code heatmaps in the fuzz report?

Coming from another language?

Java: Jazzer provides basic crash reports, no HTML dashboard. Python: Atheris writes crash files only, visualisation requires custom tools. Rust: cargo-fuzz has no built-in dashboard. Go: go test -fuzz writes to testdata, no visualisation. EK9: built-in interactive HTML dashboard with heatmaps, charts, and crash details generated by -fuzz6.

Keywords: html, crash, error, fuzz, dashboard, report, throughput, visualisation, code, statistics, phase, heatmap