Summary
Using --jobs=2 (or higher) with the v8Sandbox profile causes a crash due to an assertion failure at Fuzzer.swift:703:
assert(state == .uninitialized)
The child worker calls scheduleCorpusImport after the main fuzzer has already transitioned from .uninitialized to .corpusGeneration, violating the precondition.
Steps to Reproduce
FuzzilliCli --profile=v8Sandbox --storagePath=/opt/v8-fuzz --overwrite --timeout=500,1200 --corpus=markov --jobs=2 --logLevel=info /path/to/d8
Observed Behavior
Fuzzilli starts, completes corpus generation on the main instance, then crashes with:
Fuzzilli/Fuzzer.swift:703: Assertion failed
*** Signal 4: Backtracing from 0x7ee9132e2a30...
This occurs consistently within a few minutes of startup. --jobs=1 works fine. --jobs=2 and --jobs=4 both trigger the crash.
Expected Behavior
Multi-worker mode should work without assertion failures. The assertion at line 703 could be relaxed to allow corpus import during states other than .uninitialized, or the state transition should be synchronized so child workers don't race with the main fuzzer's initialization.
Environment
- Commit: cbade79 (Apr 8, 2026)
- Profile: v8Sandbox
- Target: V8 d8 (built with
v8_fuzzilli=true, v8_enable_sandbox=true, is_asan=true, sanitizer_coverage_flags="trace-pc-guard")
- OS: Ubuntu 22.04, 4 cores, 8GB RAM
- Swift: 6.1
Analysis
The comment at line 701-702 acknowledges this limitation:
// Currently we only allow corpus import when the fuzzer is still uninitialized.
// If necessary, this can be changed, but we'd need to be able to correctly handle
// the .waiting -> .corpusImport state transition.
In multi-worker mode, the main fuzzer transitions to .corpusGeneration before child workers have finished initializing. When a child worker then tries to synchronize its corpus with the main instance via scheduleCorpusImport, the assertion fails because the fuzzer is no longer in .uninitialized state.
A possible fix would be to either:
- Allow
scheduleCorpusImport during .corpusGeneration / .fuzzing states
- Delay the main fuzzer's state transition until all workers have completed initialization
- Use a different synchronization path for child workers that doesn't go through
scheduleCorpusImport
Summary
Using
--jobs=2(or higher) with thev8Sandboxprofile causes a crash due to an assertion failure atFuzzer.swift:703:The child worker calls
scheduleCorpusImportafter the main fuzzer has already transitioned from.uninitializedto.corpusGeneration, violating the precondition.Steps to Reproduce
Observed Behavior
Fuzzilli starts, completes corpus generation on the main instance, then crashes with:
This occurs consistently within a few minutes of startup.
--jobs=1works fine.--jobs=2and--jobs=4both trigger the crash.Expected Behavior
Multi-worker mode should work without assertion failures. The assertion at line 703 could be relaxed to allow corpus import during states other than
.uninitialized, or the state transition should be synchronized so child workers don't race with the main fuzzer's initialization.Environment
v8_fuzzilli=true,v8_enable_sandbox=true,is_asan=true,sanitizer_coverage_flags="trace-pc-guard")Analysis
The comment at line 701-702 acknowledges this limitation:
In multi-worker mode, the main fuzzer transitions to
.corpusGenerationbefore child workers have finished initializing. When a child worker then tries to synchronize its corpus with the main instance viascheduleCorpusImport, the assertion fails because the fuzzer is no longer in.uninitializedstate.A possible fix would be to either:
scheduleCorpusImportduring.corpusGeneration/.fuzzingstatesscheduleCorpusImport