Zig Version
0.16.0-dev.2261+d6b3dd25a
Steps to Reproduce and Observed Behavior
I'm seeing a crash when running zig build test --fuzz. I am only seeing this once I have two or more fuzz tests defined. I am running on a Macbook M3 Pro.
When I run the following code with zig build test --fuzz
// src/main.zig - just add two fuzz tests
test "fuzz example" {
const Context = struct {
fn testOne(context: @This(), input: []const u8) anyerror!void {
_ = context;
try std.testing.expect(!std.mem.eql(u8, "canyoufindme", input));
}
};
try std.testing.fuzz(Context{}, Context.testOne, .{});
}
test "fuzz example two" {
const Context = struct {
fn testOne(context: @This(), input: []const u8) anyerror!void {
_ = context;
try std.testing.expect(!std.mem.eql(u8, "canyoufindme", input));
}
};
try std.testing.fuzz(Context{}, Context.testOne, .{});
}
I get the following stacktrace
error(DebugAllocator): Double free detected. Allocation:
lib/std/Build/Step.zig:797:27: 0x10451c757 in allocPrintCmd (build)
return aw.toOwnedSlice();
^
lib/std/Build/Step/Run.zig:1559:60: 0x10452d8a3 in spawnChildAndCollect (build)
run.step.result_failed_command = try Step.allocPrintCmd(options.gpa, child_cwd, .{
^
lib/std/Build/Step/Run.zig:1250:52: 0x10452ecdf in runCommand (build)
const opt_generic_result = spawnChildAndCollect(run, argv, &environ_map, has_side_effects, options, fuzz_context) catch |err| term: {
^
lib/std/Build/Step/Run.zig:981:23: 0x1044e8b0f in make (build)
try runCommand(run, argv_list.items, has_side_effects, output_dir_path, options, null);
^
lib/std/Build/Step.zig:276:33: 0x1044c78e3 in make (build)
const make_result = s.makeFn(s, options);
^
lib/compiler/build_runner.zig:1336:26: 0x1044a4093 in makeStep (build)
} else if (s.make(.{
^
First free:
lib/std/Build/Step/Run.zig:1127:22: 0x104537d47 in rerunInFuzzMode (build)
fuzz.gpa.free(cmd);
^
lib/std/Build/Fuzz.zig:197:24: 0x1044c947b in fuzzWorkerRun (build)
run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {
^
lib/std/Io.zig:1114:17: 0x1044a5313 in start (build)
return @call(.auto, function, args_casted.*);
^
lib/std/Io/Threaded.zig:336:37: 0x10437efa3 in start (build)
const result = task.func(task.contextPointer());
^
lib/std/Io/Threaded.zig:1427:29: 0x1043b650b in worker (build)
runnable.startFn(runnable, &thread, t);
^
lib/std/Thread.zig:561:13: 0x10438be7f in callFn__anon_13817 (build)
@call(.auto, f, args);
^
Second free:
lib/std/Build/Step/Run.zig:1127:22: 0x104537d47 in rerunInFuzzMode (build)
fuzz.gpa.free(cmd);
^
lib/std/Build/Fuzz.zig:197:24: 0x1044c947b in fuzzWorkerRun (build)
run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {
^
lib/std/Io.zig:1114:17: 0x1044a5313 in start (build)
return @call(.auto, function, args_casted.*);
^
lib/std/Io/Threaded.zig:336:37: 0x10437efa3 in start (build)
const result = task.func(task.contextPointer());
^
lib/std/Io/Threaded.zig:1427:29: 0x1043b650b in worker (build)
runnable.startFn(runnable, &thread, t);
^
lib/std/Thread.zig:561:13: 0x10438be7f in callFn__anon_13817 (build)
@call(.auto, f, args);
^
thread 100374061 panic: reached unreachable code
lib/std/debug.zig:419:14: 0x1043416d3 in assert (build)
if (!ok) unreachable; // assertion failure
^
lib/std/Build/Step/Run.zig:1558:11: 0x10452d843 in spawnChildAndCollect (build)
assert(run.step.result_failed_command == null);
^
lib/std/Build/Step/Run.zig:1250:52: 0x10452ecdf in runCommand (build)
const opt_generic_result = spawnChildAndCollect(run, argv, &environ_map, has_side_effects, options, fuzz_context) catch |err| term: {
^
lib/std/Build/Step/Run.zig:1135:19: 0x104537d0f in rerunInFuzzMode (build)
try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, .{
^
lib/std/Build/Fuzz.zig:197:24: 0x1044c947b in fuzzWorkerRun (build)
run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {
^
lib/std/Io.zig:1114:17: 0x1044a5313 in start (build)
return @call(.auto, function, args_casted.*);
^
lib/std/Io/Threaded.zig:336:37: 0x10437efa3 in start (build)
const result = task.func(task.contextPointer());
^
lib/std/Io/Threaded.zig:1427:29: 0x1043b650b in worker (build)
runnable.startFn(runnable, &thread, t);
^
lib/std/Thread.zig:561:13: 0x10438be7f in callFn__anon_13817 (build)
@call(.auto, f, args);
^
lib/std/Thread.zig:832:30: 0x10437e1cb in entryFn (build)
return callFn(f, args_ptr.*);
Expected Behavior
I would expect to have both fuzz tests run in parallel
### Zig Version
0.16.0-dev.2261+d6b3dd25a
### Steps to Reproduce and Observed Behavior
I'm seeing a crash when running `zig build test --fuzz`. I am only seeing this once I have two or more fuzz tests defined. I am running on a Macbook M3 Pro.
When I run the following code with `zig build test --fuzz`
```
// src/main.zig - just add two fuzz tests
test "fuzz example" {
const Context = struct {
fn testOne(context: @This(), input: []const u8) anyerror!void {
_ = context;
try std.testing.expect(!std.mem.eql(u8, "canyoufindme", input));
}
};
try std.testing.fuzz(Context{}, Context.testOne, .{});
}
test "fuzz example two" {
const Context = struct {
fn testOne(context: @This(), input: []const u8) anyerror!void {
_ = context;
try std.testing.expect(!std.mem.eql(u8, "canyoufindme", input));
}
};
try std.testing.fuzz(Context{}, Context.testOne, .{});
}
```
I get the following stacktrace
```
error(DebugAllocator): Double free detected. Allocation:
lib/std/Build/Step.zig:797:27: 0x10451c757 in allocPrintCmd (build)
return aw.toOwnedSlice();
^
lib/std/Build/Step/Run.zig:1559:60: 0x10452d8a3 in spawnChildAndCollect (build)
run.step.result_failed_command = try Step.allocPrintCmd(options.gpa, child_cwd, .{
^
lib/std/Build/Step/Run.zig:1250:52: 0x10452ecdf in runCommand (build)
const opt_generic_result = spawnChildAndCollect(run, argv, &environ_map, has_side_effects, options, fuzz_context) catch |err| term: {
^
lib/std/Build/Step/Run.zig:981:23: 0x1044e8b0f in make (build)
try runCommand(run, argv_list.items, has_side_effects, output_dir_path, options, null);
^
lib/std/Build/Step.zig:276:33: 0x1044c78e3 in make (build)
const make_result = s.makeFn(s, options);
^
lib/compiler/build_runner.zig:1336:26: 0x1044a4093 in makeStep (build)
} else if (s.make(.{
^
First free:
lib/std/Build/Step/Run.zig:1127:22: 0x104537d47 in rerunInFuzzMode (build)
fuzz.gpa.free(cmd);
^
lib/std/Build/Fuzz.zig:197:24: 0x1044c947b in fuzzWorkerRun (build)
run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {
^
lib/std/Io.zig:1114:17: 0x1044a5313 in start (build)
return @call(.auto, function, args_casted.*);
^
lib/std/Io/Threaded.zig:336:37: 0x10437efa3 in start (build)
const result = task.func(task.contextPointer());
^
lib/std/Io/Threaded.zig:1427:29: 0x1043b650b in worker (build)
runnable.startFn(runnable, &thread, t);
^
lib/std/Thread.zig:561:13: 0x10438be7f in callFn__anon_13817 (build)
@call(.auto, f, args);
^
Second free:
lib/std/Build/Step/Run.zig:1127:22: 0x104537d47 in rerunInFuzzMode (build)
fuzz.gpa.free(cmd);
^
lib/std/Build/Fuzz.zig:197:24: 0x1044c947b in fuzzWorkerRun (build)
run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {
^
lib/std/Io.zig:1114:17: 0x1044a5313 in start (build)
return @call(.auto, function, args_casted.*);
^
lib/std/Io/Threaded.zig:336:37: 0x10437efa3 in start (build)
const result = task.func(task.contextPointer());
^
lib/std/Io/Threaded.zig:1427:29: 0x1043b650b in worker (build)
runnable.startFn(runnable, &thread, t);
^
lib/std/Thread.zig:561:13: 0x10438be7f in callFn__anon_13817 (build)
@call(.auto, f, args);
^
thread 100374061 panic: reached unreachable code
lib/std/debug.zig:419:14: 0x1043416d3 in assert (build)
if (!ok) unreachable; // assertion failure
^
lib/std/Build/Step/Run.zig:1558:11: 0x10452d843 in spawnChildAndCollect (build)
assert(run.step.result_failed_command == null);
^
lib/std/Build/Step/Run.zig:1250:52: 0x10452ecdf in runCommand (build)
const opt_generic_result = spawnChildAndCollect(run, argv, &environ_map, has_side_effects, options, fuzz_context) catch |err| term: {
^
lib/std/Build/Step/Run.zig:1135:19: 0x104537d0f in rerunInFuzzMode (build)
try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, .{
^
lib/std/Build/Fuzz.zig:197:24: 0x1044c947b in fuzzWorkerRun (build)
run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {
^
lib/std/Io.zig:1114:17: 0x1044a5313 in start (build)
return @call(.auto, function, args_casted.*);
^
lib/std/Io/Threaded.zig:336:37: 0x10437efa3 in start (build)
const result = task.func(task.contextPointer());
^
lib/std/Io/Threaded.zig:1427:29: 0x1043b650b in worker (build)
runnable.startFn(runnable, &thread, t);
^
lib/std/Thread.zig:561:13: 0x10438be7f in callFn__anon_13817 (build)
@call(.auto, f, args);
^
lib/std/Thread.zig:832:30: 0x10437e1cb in entryFn (build)
return callFn(f, args_ptr.*);
```
### Expected Behavior
I would expect to have both fuzz tests run in parallel