Back to V8

Minimize Reproducer

agents/skills/minimize-reproducer/SKILL.md

15.1.1924.3 KB
Original Source

Minimize Reproducer

Workflow

1. Identify the Failure Signature

Before minimizing, understand exactly what "reproduction" looks like.

  • Exact Command: e.g., `out/x64.release/d8 --fuzzing poc.js`
  • Failure Type: Crash (segfault, abort), Assertion failure, Sandbox violation, or Incorrect output.
  • Stability Check: Initially check how stable the reproduction is. If it's flaky, you'll need to run it multiple times at every step. Use the bundled `repro_check.sh` script.

2. Command-Line Flag Minimization

Find the minimal set of V8 flags required to reproduce the issue.

  • Batch Removal: Start by removing larger batches of flags (e.g., all flags starting with `--no-` or all optimization flags).
  • One-by-One: Progressively remove individual flags until only the essential ones remain.
  • Common Critical Flags: Pay attention to flags like `--sandbox-fuzzing`, `--memory-corruption-via-watchpoints`, or `--turbofan`, as these often control the underlying feature being tested.
  • Validation: Test reproduction after every step. If it stops failing, restore the last flag removed.

3. File Minimization (The Iterative Phase)

Reduce the input JavaScript file systematically. Always work on a copy (e.g., `poc-copy.js`) and maintain a `poc-min.js` as your "best known" version.

  • Remove Large Blocks: Start by removing entire functions, classes, or large blocks of code (e.g., fuzzer boilerplate, unused libraries).
  • Binary Search: If a large block is present, try removing half. If it still fails, that half was unnecessary.
  • Remove Individual Lines: Once large blocks are gone, try removing individual lines.
  • Inline Functions: If a function is called only once, inline its content and remove the definition.
  • Simplify Wrappers: Remove `try-catch` blocks but retain the code inside the `try` block.
  • Stabilize with Loops: If a reproduction is flaky (e.g., it only fails 10% of the time), add a loop around the triggering logic to increase the failure probability to 100%.

4. Wasm Minimization

WebAssembly reproductions often start as opaque Uint8Array blobs. Converting these to readable WasmModuleBuilder JS is critical for understanding and minimizing the logic.

  • Convert Early with wami: Use the wami tool to automatically generate WasmModuleBuilder code from a Wasm binary. This is much less error-prone than manual conversion.
    • Command: out/x64.release/wami --mjsunit input.wasm > poc.js
  • Handle WasmModuleBuilder Specifics:
    • Recursive Types: Be careful with recursive type definitions; ensure they are correctly indexed.
    • Reference Types: When specifying indices for heap types (e.g., in struct.get), use wasmRefNullType(typeIndex) or similar helpers where the builder expects a type object rather than a raw integer.
    • Signature Validation: After conversion, verify that the module still reproduces the original issue. WasmModuleBuilder might require minor manual adjustments if the original binary had subtle validation errors.

5. Special API Handling (e.g., Sandbox API)

  • Offset Alignment: Some APIs (like Sandbox.markForCorruptionOnAccess) require specific alignments (e.g., tagged-size-aligned offsets like 8, 12, or 16).
  • Object Context: Ensure the object being manipulated (e.g., a String) is large enough for the offset being targeted. Use %DebugPrint(obj) with --allow-natives-syntax to inspect the internal structure.

6. Clean and Polish

  • Rename Variables: Obfuscated names like __v_0 should be renamed to something descriptive like str or targetObj.
  • Readability > Size: A 20-line file that is easy to understand is better than a 10-line file that is completely cryptic.
  • Self-Contained: Ensure the final poc-min.js is completely self-contained and does not rely on external fuzzer libraries unless strictly necessary.

Guidelines

  • Work on a copy: Never modify the original reproduction file directly.
  • Validate EVERY change: A single character change can stop a bug from reproducing. Always verify.
  • Keep a "Best Version": Always update your `-min.js` file as soon as you find a smaller working version. This allows you to easily backtrack if a more aggressive minimization fails.