authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-04-11 00:59:11+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-04-11 00:59:11+02:00
logd6f43caadf30dce2ad6f8fa938482855e08e6700
treebd69fea5940f040ba272c4c98cfc11300d30c4e7
parent8111d3d63cf3662b5aecbd0ddd10567e025694a7
parent4a1383d987130978bc66ba7cd7172c398684978d

Merge pull request 'audit: handle process.Child.Term exhaustively and give useful exit information on process exit' (#31018) from murtaza/zig:child.term-audit into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31018 Reviewed-by: Alex Rønne Petersen <alex@alexrp.com>

20 files changed, 140 insertions(+), 72 deletions(-)

lib/compiler/reduce.zig+5-1
...@@ -291,7 +291,11 @@ fn termToInteresting(term: std.process.Child.Term) Interestingness {...@@ -291,7 +291,11 @@ fn termToInteresting(term: std.process.Child.Term) Interestingness {
291 std.debug.print("interestingness check terminated with signal {t}\n", .{sig});291 std.debug.print("interestingness check terminated with signal {t}\n", .{sig});
292 return .boring;292 return .boring;
293 },293 },
294 else => {294 .stopped => |sig| {
295 std.debug.print("interestingness check stopped with signal {t}\n", .{sig});
296 return .boring;
297 },
298 .unknown => {
295 std.debug.print("interestingness check aborted unexpectedly\n", .{});299 std.debug.print("interestingness check aborted unexpectedly\n", .{});
296 return .boring;300 return .boring;
297 },301 },
lib/compiler/std-docs.zig+8-1
...@@ -423,7 +423,14 @@ fn buildWasmBinary(...@@ -423,7 +423,14 @@ fn buildWasmBinary(
423 );423 );
424 return error.WasmCompilationFailed;424 return error.WasmCompilationFailed;
425 },425 },
426 .stopped, .unknown => {426 .stopped => |sig| {
427 std.log.err(
428 "the following command stopped unexpectedly with signal {t}:\n{s}",
429 .{ sig, try std.Build.Step.allocPrintCmd(arena, .inherit, null, argv.items) },
430 );
431 return error.WasmCompilationFailed;
432 },
433 .unknown => {
427 std.log.err(434 std.log.err(
428 "the following command terminated unexpectedly:\n{s}",435 "the following command terminated unexpectedly:\n{s}",
429 .{try std.Build.Step.allocPrintCmd(arena, .inherit, null, argv.items)},436 .{try std.Build.Step.allocPrintCmd(arena, .inherit, null, argv.items)},
lib/std/Build.zig+2-2
...@@ -1899,11 +1899,11 @@ pub fn runAllowFail(...@@ -1899,11 +1899,11 @@ pub fn runAllowFail(
1899 }1899 }
1900 return stdout;1900 return stdout;
1901 },1901 },
1902 .signal => |sig| {1902 .signal, .stopped => |sig| {
1903 out_code.* = @as(u8, @truncate(@intFromEnum(sig)));1903 out_code.* = @as(u8, @truncate(@intFromEnum(sig)));
1904 return error.ProcessTerminated;1904 return error.ProcessTerminated;
1905 },1905 },
1906 .stopped, .unknown => |code| {1906 .unknown => |code| {
1907 out_code.* = @as(u8, @truncate(code));1907 out_code.* = @as(u8, @truncate(code));
1908 return error.ProcessTerminated;1908 return error.ProcessTerminated;
1909 },1909 },
lib/std/Build/Step.zig+6-13
...@@ -725,19 +725,12 @@ pub inline fn handleChildProcUnsupported(s: *Step) error{ OutOfMemory, MakeFaile...@@ -725,19 +725,12 @@ pub inline fn handleChildProcUnsupported(s: *Step) error{ OutOfMemory, MakeFaile
725/// Asserts that the caller has already populated `s.result_failed_command`.725/// Asserts that the caller has already populated `s.result_failed_command`.
726pub fn handleChildProcessTerm(s: *Step, term: std.process.Child.Term) error{ MakeFailed, OutOfMemory }!void {726pub fn handleChildProcessTerm(s: *Step, term: std.process.Child.Term) error{ MakeFailed, OutOfMemory }!void {
727 assert(s.result_failed_command != null);727 assert(s.result_failed_command != null);
728 switch (term) {728 return switch (term) {
729 .exited => |code| {729 .exited => |code| if (code != 0) s.fail("process exited with error code {d}", .{code}),
730 if (code != 0) {730 .signal => |sig| s.fail("process terminated with signal {t}", .{sig}),
731 return s.fail("process exited with error code {d}", .{code});731 .stopped => |sig| s.fail("process stopped with signal {t}", .{sig}),
732 }732 .unknown => s.fail("process terminated unexpectedly", .{}),
733 },733 };
734 .signal => |sig| {
735 return s.fail("process terminated with signal {t}", .{sig});
736 },
737 .stopped, .unknown => {
738 return s.fail("process terminated unexpectedly", .{});
739 },
740 }
741}734}
742735
743pub fn allocPrintCmd(736pub fn allocPrintCmd(
lib/std/Build/Step/Run.zig+3-3
...@@ -1173,7 +1173,7 @@ fn formatTerm(term: ?process.Child.Term, w: *std.Io.Writer) std.Io.Writer.Error!...@@ -1173,7 +1173,7 @@ fn formatTerm(term: ?process.Child.Term, w: *std.Io.Writer) std.Io.Writer.Error!
1173 if (term) |t| switch (t) {1173 if (term) |t| switch (t) {
1174 .exited => |code| try w.print("exited with code {d}", .{code}),1174 .exited => |code| try w.print("exited with code {d}", .{code}),
1175 .signal => |sig| try w.print("terminated with signal {t}", .{sig}),1175 .signal => |sig| try w.print("terminated with signal {t}", .{sig}),
1176 .stopped => |sig| try w.print("stopped with signal {d}", .{sig}),1176 .stopped => |sig| try w.print("stopped with signal {t}", .{sig}),
1177 .unknown => |code| try w.print("terminated for unknown reason with code {d}", .{code}),1177 .unknown => |code| try w.print("terminated for unknown reason with code {d}", .{code}),
1178 } else {1178 } else {
1179 try w.writeAll("exited with any code");1179 try w.writeAll("exited with any code");
...@@ -2804,8 +2804,8 @@ fn hashStdIo(hh: *std.Build.Cache.HashHelper, stdio: StdIo) void {...@@ -2804,8 +2804,8 @@ fn hashStdIo(hh: *std.Build.Cache.HashHelper, stdio: StdIo) void {
2804 .expect_term => |term| {2804 .expect_term => |term| {
2805 hh.add(@as(std.meta.Tag(process.Child.Term), term));2805 hh.add(@as(std.meta.Tag(process.Child.Term), term));
2806 switch (term) {2806 switch (term) {
2807 inline .exited, .signal => |x| hh.add(x),2807 inline .exited, .signal, .stopped => |x| hh.add(x),
2808 .stopped, .unknown => |x| hh.add(x),2808 .unknown => |x| hh.add(x),
2809 }2809 }
2810 },2810 },
2811 }2811 }
lib/std/Build/WebServer.zig+8-1
...@@ -681,7 +681,14 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim...@@ -681,7 +681,14 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim
681 );681 );
682 return error.WasmCompilationFailed;682 return error.WasmCompilationFailed;
683 },683 },
684 .stopped, .unknown => {684 .stopped => |sig| {
685 log.err(
686 "the following command stopped unexpectedly with signal {t}:\n{s}",
687 .{ sig, try Build.Step.allocPrintCmd(arena, .inherit, null, argv.items) },
688 );
689 return error.WasmCompilationFailed;
690 },
691 .unknown => {
685 log.err(692 log.err(
686 "the following command terminated unexpectedly:\n{s}",693 "the following command terminated unexpectedly:\n{s}",
687 .{try Build.Step.allocPrintCmd(arena, .inherit, null, argv.items)},694 .{try Build.Step.allocPrintCmd(arena, .inherit, null, argv.items)},
lib/std/Io/Threaded.zig+1-1
...@@ -15281,7 +15281,7 @@ fn childWaitPosix(child: *process.Child) process.Child.WaitError!process.Child.T...@@ -15281,7 +15281,7 @@ fn childWaitPosix(child: *process.Child) process.Child.WaitError!process.Child.T
15281 return switch (code) {15281 return switch (code) {
15282 .EXITED => .{ .exited = @truncate(status) },15282 .EXITED => .{ .exited = @truncate(status) },
15283 .KILLED, .DUMPED => .{ .signal = @enumFromInt(status) },15283 .KILLED, .DUMPED => .{ .signal = @enumFromInt(status) },
15284 .TRAPPED, .STOPPED => .{ .stopped = status },15284 .TRAPPED, .STOPPED => .{ .stopped = @enumFromInt(status) },
15285 _, .CONTINUED => .{ .unknown = status },15285 _, .CONTINUED => .{ .unknown = status },
15286 };15286 };
15287 },15287 },
lib/std/Io/Uring.zig+1-1
...@@ -4729,7 +4729,7 @@ fn childWait(userdata: ?*anyopaque, child: *process.Child) process.Child.WaitErr...@@ -4729,7 +4729,7 @@ fn childWait(userdata: ?*anyopaque, child: *process.Child) process.Child.WaitErr
4729 return switch (code) {4729 return switch (code) {
4730 .EXITED => .{ .exited = @truncate(status) },4730 .EXITED => .{ .exited = @truncate(status) },
4731 .KILLED, .DUMPED => .{ .signal = @enumFromInt(status) },4731 .KILLED, .DUMPED => .{ .signal = @enumFromInt(status) },
4732 .TRAPPED, .STOPPED => .{ .stopped = status },4732 .TRAPPED, .STOPPED => .{ .stopped = @enumFromInt(status) },
4733 _, .CONTINUED => .{ .unknown = status },4733 _, .CONTINUED => .{ .unknown = status },
4734 };4734 };
4735 },4735 },
lib/std/c.zig+17-17
...@@ -3721,14 +3721,14 @@ pub const W = switch (native_os) {...@@ -3721,14 +3721,14 @@ pub const W = switch (native_os) {
3721 pub fn TERMSIG(x: u32) SIG {3721 pub fn TERMSIG(x: u32) SIG {
3722 return @enumFromInt(status(x));3722 return @enumFromInt(status(x));
3723 }3723 }
3724 pub fn STOPSIG(x: u32) u32 {3724 pub fn STOPSIG(x: u32) SIG {
3725 return x >> 8;3725 return @enumFromInt(x >> 8);
3726 }3726 }
3727 pub fn IFEXITED(x: u32) bool {3727 pub fn IFEXITED(x: u32) bool {
3728 return status(x) == 0;3728 return status(x) == 0;
3729 }3729 }
3730 pub fn IFSTOPPED(x: u32) bool {3730 pub fn IFSTOPPED(x: u32) bool {
3731 return status(x) == stopped and STOPSIG(x) != 0x13;3731 return status(x) == stopped and @as(u32, @intFromEnum(STOPSIG(x))) != 0x13;
3732 }3732 }
3733 pub fn IFSIGNALED(x: u32) bool {3733 pub fn IFSIGNALED(x: u32) bool {
3734 return status(x) != stopped and status(x) != 0;3734 return status(x) != stopped and status(x) != 0;
...@@ -3754,8 +3754,8 @@ pub const W = switch (native_os) {...@@ -3754,8 +3754,8 @@ pub const W = switch (native_os) {
3754 pub fn TERMSIG(s: u32) SIG {3754 pub fn TERMSIG(s: u32) SIG {
3755 return @enumFromInt(s & 0x7f);3755 return @enumFromInt(s & 0x7f);
3756 }3756 }
3757 pub fn STOPSIG(s: u32) u32 {3757 pub fn STOPSIG(s: u32) SIG {
3758 return EXITSTATUS(s);3758 return @enumFromInt(EXITSTATUS(s));
3759 }3759 }
3760 pub fn IFEXITED(s: u32) bool {3760 pub fn IFEXITED(s: u32) bool {
3761 return (s & 0x7f) == 0;3761 return (s & 0x7f) == 0;
...@@ -3782,8 +3782,8 @@ pub const W = switch (native_os) {...@@ -3782,8 +3782,8 @@ pub const W = switch (native_os) {
3782 pub fn TERMSIG(s: u32) SIG {3782 pub fn TERMSIG(s: u32) SIG {
3783 return @enumFromInt(s & 0x7f);3783 return @enumFromInt(s & 0x7f);
3784 }3784 }
3785 pub fn STOPSIG(s: u32) u32 {3785 pub fn STOPSIG(s: u32) SIG {
3786 return EXITSTATUS(s);3786 return @enumFromInt(EXITSTATUS(s));
3787 }3787 }
3788 pub fn IFEXITED(s: u32) bool {3788 pub fn IFEXITED(s: u32) bool {
3789 return (s & 0x7f) == 0;3789 return (s & 0x7f) == 0;
...@@ -3816,8 +3816,8 @@ pub const W = switch (native_os) {...@@ -3816,8 +3816,8 @@ pub const W = switch (native_os) {
3816 pub fn TERMSIG(s: u32) SIG {3816 pub fn TERMSIG(s: u32) SIG {
3817 return @enumFromInt(s & 0x7f);3817 return @enumFromInt(s & 0x7f);
3818 }3818 }
3819 pub fn STOPSIG(s: u32) u32 {3819 pub fn STOPSIG(s: u32) SIG {
3820 return EXITSTATUS(s);3820 return @enumFromInt(EXITSTATUS(s));
3821 }3821 }
3822 pub fn IFEXITED(s: u32) bool {3822 pub fn IFEXITED(s: u32) bool {
3823 return (s & 0x7f) == 0;3823 return (s & 0x7f) == 0;
...@@ -3850,8 +3850,8 @@ pub const W = switch (native_os) {...@@ -3850,8 +3850,8 @@ pub const W = switch (native_os) {
3850 pub fn TERMSIG(s: u32) SIG {3850 pub fn TERMSIG(s: u32) SIG {
3851 return @enumFromInt(s & 0x7f);3851 return @enumFromInt(s & 0x7f);
3852 }3852 }
3853 pub fn STOPSIG(s: u32) u32 {3853 pub fn STOPSIG(s: u32) SIG {
3854 return EXITSTATUS(s);3854 return @enumFromInt(EXITSTATUS(s));
3855 }3855 }
3856 pub fn IFEXITED(s: u32) bool {3856 pub fn IFEXITED(s: u32) bool {
3857 return (s & 0x7f) == 0;3857 return (s & 0x7f) == 0;
...@@ -3879,8 +3879,8 @@ pub const W = switch (native_os) {...@@ -3879,8 +3879,8 @@ pub const W = switch (native_os) {
3879 return @enumFromInt((s >> 8) & 0xff);3879 return @enumFromInt((s >> 8) & 0xff);
3880 }3880 }
38813881
3882 pub fn STOPSIG(s: u32) u32 {3882 pub fn STOPSIG(s: u32) SIG {
3883 return (s >> 16) & 0xff;3883 return @enumFromInt((s >> 16) & 0xff);
3884 }3884 }
38853885
3886 pub fn IFEXITED(s: u32) bool {3886 pub fn IFEXITED(s: u32) bool {
...@@ -3906,8 +3906,8 @@ pub const W = switch (native_os) {...@@ -3906,8 +3906,8 @@ pub const W = switch (native_os) {
3906 pub fn TERMSIG(s: u32) SIG {3906 pub fn TERMSIG(s: u32) SIG {
3907 return @enumFromInt(s & 0x7f);3907 return @enumFromInt(s & 0x7f);
3908 }3908 }
3909 pub fn STOPSIG(s: u32) u32 {3909 pub fn STOPSIG(s: u32) SIG {
3910 return EXITSTATUS(s);3910 return @enumFromInt(EXITSTATUS(s));
3911 }3911 }
3912 pub fn IFEXITED(s: u32) bool {3912 pub fn IFEXITED(s: u32) bool {
3913 return (s & 0x7f) == 0;3913 return (s & 0x7f) == 0;
...@@ -3938,8 +3938,8 @@ pub const W = switch (native_os) {...@@ -3938,8 +3938,8 @@ pub const W = switch (native_os) {
3938 return @intCast((s & 0xff00) >> 8);3938 return @intCast((s & 0xff00) >> 8);
3939 }3939 }
39403940
3941 pub fn STOPSIG(s: u32) u32 {3941 pub fn STOPSIG(s: u32) SIG {
3942 return EXITSTATUS(s);3942 return @enumFromInt(EXITSTATUS(s));
3943 }3943 }
39443944
3945 pub fn TERMSIG(s: u32) SIG {3945 pub fn TERMSIG(s: u32) SIG {
lib/std/os/emscripten.zig+1-1
...@@ -212,7 +212,7 @@ pub const W = struct {...@@ -212,7 +212,7 @@ pub const W = struct {
212 return @enumFromInt(s & 0x7f);212 return @enumFromInt(s & 0x7f);
213 }213 }
214 pub fn STOPSIG(s: u32) u32 {214 pub fn STOPSIG(s: u32) u32 {
215 return EXITSTATUS(s);215 return @enumFromInt(EXITSTATUS(s));
216 }216 }
217 pub fn IFEXITED(s: u32) bool {217 pub fn IFEXITED(s: u32) bool {
218 return (s & 0x7f) == 0;218 return (s & 0x7f) == 0;
lib/std/os/linux.zig+2-2
...@@ -3883,8 +3883,8 @@ pub const W = struct {...@@ -3883,8 +3883,8 @@ pub const W = struct {
3883 pub fn TERMSIG(s: u32) SIG {3883 pub fn TERMSIG(s: u32) SIG {
3884 return @enumFromInt(s & 0x7f);3884 return @enumFromInt(s & 0x7f);
3885 }3885 }
3886 pub fn STOPSIG(s: u32) u32 {3886 pub fn STOPSIG(s: u32) SIG {
3887 return EXITSTATUS(s);3887 return @enumFromInt(EXITSTATUS(s));
3888 }3888 }
3889 pub fn IFEXITED(s: u32) bool {3889 pub fn IFEXITED(s: u32) bool {
3890 return (s & 0x7f) == 0;3890 return (s & 0x7f) == 0;
lib/std/process/Child.zig+1-1
...@@ -94,7 +94,7 @@ pub const ResourceUsageStatistics = struct {...@@ -94,7 +94,7 @@ pub const ResourceUsageStatistics = struct {
94pub const Term = union(enum) {94pub const Term = union(enum) {
95 exited: u8,95 exited: u8,
96 signal: std.posix.SIG,96 signal: std.posix.SIG,
97 stopped: u32,97 stopped: std.posix.SIG,
98 unknown: u32,98 unknown: u32,
99};99};
100100
lib/std/zig/system.zig+18-4
...@@ -1185,11 +1185,25 @@ fn detectAndroidApiLevel(io: Io) !u32 {...@@ -1185,11 +1185,25 @@ fn detectAndroidApiLevel(io: Io) !u32 {
1185 return error.ApiLevelQueryFailed;1185 return error.ApiLevelQueryFailed;
1186 };1186 };
11871187
1188 const term = try child.wait(io);1188 switch (try child.wait(io)) {
1189 if (term != .exited or term.exited != 0) {1189 .exited => |code| if (code != 0) {
1190 std.log.err("getprop terminated abnormally: {}", .{term});1190 std.log.err("getprop terminated abnormally with exit code: {d}", .{code});
1191 return error.ApiLevelQueryFailed;1191 return error.ApiLevelQueryFailed;
1192 },
1193 .signal => |sig| {
1194 std.log.err("getprop terminated abnormally with signal: {t}", .{sig});
1195 return error.ApiLevelQueryFailed;
1196 },
1197 .stopped => |sig| {
1198 std.log.err("getprop stopped abnormally with signal: {t}", .{sig});
1199 return error.ApiLevelQueryFailed;
1200 },
1201 .unknown => {
1202 std.log.err("getprop terminated abnormally", .{});
1203 return error.ApiLevelQueryFailed;
1204 },
1192 }1205 }
1206
1193 return api_level;1207 return api_level;
1194}1208}
11951209
src/Compilation.zig+10-2
...@@ -5870,7 +5870,11 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5870,7 +5870,11 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5870 log.err("clang failed with stderr: {s}", .{stderr});5870 log.err("clang failed with stderr: {s}", .{stderr});
5871 return comp.failCObj(c_object, "clang terminated with signal {t}", .{sig});5871 return comp.failCObj(c_object, "clang terminated with signal {t}", .{sig});
5872 },5872 },
5873 else => {5873 .stopped => |sig| {
5874 log.err("clang failed with stderr: {s}", .{stderr});
5875 return comp.failCObj(c_object, "clang stopped with signal {t}", .{sig});
5876 },
5877 .unknown => {
5874 log.err("clang terminated with stderr: {s}", .{stderr});5878 log.err("clang terminated with stderr: {s}", .{stderr});
5875 return comp.failCObj(c_object, "clang terminated unexpectedly", .{});5879 return comp.failCObj(c_object, "clang terminated unexpectedly", .{});
5876 },5880 },
...@@ -6297,7 +6301,11 @@ fn spawnZigRc(...@@ -6297,7 +6301,11 @@ fn spawnZigRc(
6297 log.err("zig rc signaled {t} with stderr:\n{s}", .{ sig, stderr });6301 log.err("zig rc signaled {t} with stderr:\n{s}", .{ sig, stderr });
6298 return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{});6302 return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{});
6299 },6303 },
6300 else => {6304 .stopped => |sig| {
6305 log.err("zig rc stopped {t} with stderr:\n{s}", .{ sig, stderr });
6306 return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{});
6307 },
6308 .unknown => {
6301 log.err("zig rc terminated with stderr:\n{s}", .{stderr});6309 log.err("zig rc terminated with stderr:\n{s}", .{stderr});
6302 return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{});6310 return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{});
6303 },6311 },
src/link/Lld.zig+1-1
...@@ -1733,7 +1733,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi...@@ -1733,7 +1733,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi
1733 },1733 },
1734 .stopped => |sig| {1734 .stopped => |sig| {
1735 if (comp.clang_passthrough_mode) std.process.abort();1735 if (comp.clang_passthrough_mode) std.process.abort();
1736 return diags.fail("{s} stopped with signal {d} and stderr:\n{s}", .{ argv[0], sig, stderr });1736 return diags.fail("{s} stopped with signal {t} and stderr:\n{s}", .{ argv[0], sig, stderr });
1737 },1737 },
1738 .unknown => |code| {1738 .unknown => |code| {
1739 if (comp.clang_passthrough_mode) std.process.abort();1739 if (comp.clang_passthrough_mode) std.process.abort();
src/main.zig+15-3
...@@ -4580,7 +4580,11 @@ fn runOrTest(...@@ -4580,7 +4580,11 @@ fn runOrTest(
4580 const cmd = try std.mem.join(arena, " ", argv.items);4580 const cmd = try std.mem.join(arena, " ", argv.items);
4581 fatal("the following command terminated with signal {t}:\n{s}", .{ sig, cmd });4581 fatal("the following command terminated with signal {t}:\n{s}", .{ sig, cmd });
4582 },4582 },
4583 else => {4583 .stopped => |sig| {
4584 const cmd = try std.mem.join(arena, " ", argv.items);
4585 fatal("the following command stopped with signal {t}:\n{s}", .{ sig, cmd });
4586 },
4587 .unknown => {
4584 process.exit(1);4588 process.exit(1);
4585 },4589 },
4586 }4590 }
...@@ -5630,7 +5634,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,...@@ -5630,7 +5634,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,
5630 const cmd = try std.mem.join(arena, " ", child_argv.items);5634 const cmd = try std.mem.join(arena, " ", child_argv.items);
5631 fatal("the following build command terminated with signal {t}:\n{s}", .{ sig, cmd });5635 fatal("the following build command terminated with signal {t}:\n{s}", .{ sig, cmd });
5632 },5636 },
5633 else => {5637 .stopped => |sig| {
5638 const cmd = try std.mem.join(arena, " ", child_argv.items);
5639 fatal("the following build command stopped with signal {t}:\n{s}", .{ sig, cmd });
5640 },
5641 .unknown => {
5634 const cmd = try std.mem.join(arena, " ", child_argv.items);5642 const cmd = try std.mem.join(arena, " ", child_argv.items);
5635 fatal("the following build command crashed:\n{s}", .{cmd});5643 fatal("the following build command crashed:\n{s}", .{cmd});
5636 },5644 },
...@@ -5932,7 +5940,11 @@ fn jitCmdInner(...@@ -5932,7 +5940,11 @@ fn jitCmdInner(
5932 const cmd = try std.mem.join(arena, " ", child_argv.items);5940 const cmd = try std.mem.join(arena, " ", child_argv.items);
5933 fatal("the following build command terminated with signal {t}:\n{s}", .{ sig, cmd });5941 fatal("the following build command terminated with signal {t}:\n{s}", .{ sig, cmd });
5934 },5942 },
5935 else => {5943 .stopped => |sig| {
5944 const cmd = try std.mem.join(arena, " ", child_argv.items);
5945 fatal("the following build command stopped with signal {t}:\n{s}", .{ sig, cmd });
5946 },
5947 .unknown => {
5936 const cmd = try std.mem.join(arena, " ", child_argv.items);5948 const cmd = try std.mem.join(arena, " ", child_argv.items);
5937 fatal("the following build command crashed:\n{s}", .{cmd});5949 fatal("the following build command crashed:\n{s}", .{cmd});
5938 },5950 },
tools/doctest.zig+6-1
...@@ -1141,7 +1141,12 @@ fn run(...@@ -1141,7 +1141,12 @@ fn run(
1141 dumpArgs(args);1141 dumpArgs(args);
1142 return error.ChildCrashed;1142 return error.ChildCrashed;
1143 },1143 },
1144 else => {1144 .stopped => |sig| {
1145 std.debug.print("{s}\nThe following command stopped with signal {t}:\n", .{ result.stderr, sig });
1146 dumpArgs(args);
1147 return error.ChildCrashed;
1148 },
1149 .unknown => {
1145 std.debug.print("{s}\nThe following command crashed:\n", .{result.stderr});1150 std.debug.print("{s}\nThe following command crashed:\n", .{result.stderr});
1146 dumpArgs(args);1151 dumpArgs(args);
1147 return error.ChildCrashed;1152 return error.ChildCrashed;
tools/incr-check.zig+16-14
...@@ -568,7 +568,10 @@ const Eval = struct {...@@ -568,7 +568,10 @@ const Eval = struct {
568 .signal => |sig| {568 .signal => |sig| {
569 eval.fatal("generated executable '{s}' terminated with signal {t}", .{ binary_path, sig });569 eval.fatal("generated executable '{s}' terminated with signal {t}", .{ binary_path, sig });
570 },570 },
571 .stopped, .unknown => {571 .stopped => |sig| {
572 eval.fatal("generated executable '{s}' stopped with signal {t}", .{ binary_path, sig });
573 },
574 .unknown => {
572 eval.fatal("generated executable '{s}' terminated unexpectedly", .{binary_path});575 eval.fatal("generated executable '{s}' terminated unexpectedly", .{binary_path});
573 },576 },
574 }577 }
...@@ -627,19 +630,17 @@ const Eval = struct {...@@ -627,19 +630,17 @@ const Eval = struct {
627 }) catch |err| {630 }) catch |err| {
628 eval.fatal("failed to spawn zig cc for '{s}': {t}", .{ c_path, err });631 eval.fatal("failed to spawn zig cc for '{s}': {t}", .{ c_path, err });
629 };632 };
633
634 if (result.term == .exited and result.term.exited == 0) return;
635
636 if (result.stderr.len != 0) {
637 std.log.err("zig cc stderr:\n{s}", .{result.stderr});
638 }
630 switch (result.term) {639 switch (result.term) {
631 .exited => |code| if (code != 0) {640 .exited => |code| eval.fatal("zig cc for '{s}' failed with code {d}", .{ c_path, code }),
632 if (result.stderr.len != 0) {641 .signal => |sig| eval.fatal("zig cc for '{s}' terminated unexpectedly with signal {t}", .{ c_path, sig }),
633 std.log.err("zig cc stderr:\n{s}", .{result.stderr});642 .stopped => |sig| eval.fatal("zig cc for '{s}' stopped unexpectedly with signal {t}", .{ c_path, sig }),
634 }643 .unknown => eval.fatal("zig cc for '{s}' terminated unexpectedly", .{c_path}),
635 eval.fatal("zig cc for '{s}' failed with code {d}", .{ c_path, code });
636 },
637 .signal, .stopped, .unknown => {
638 if (result.stderr.len != 0) {
639 std.log.err("zig cc stderr:\n{s}", .{result.stderr});
640 }
641 eval.fatal("zig cc for '{s}' terminated unexpectedly", .{c_path});
642 },
643 }644 }
644 }645 }
645646
...@@ -918,7 +919,8 @@ fn waitChild(child: *std.process.Child, eval: *Eval) void {...@@ -918,7 +919,8 @@ fn waitChild(child: *std.process.Child, eval: *Eval) void {
918 switch (term) {919 switch (term) {
919 .exited => |code| if (code != 0) eval.fatal("compiler failed with code {d}", .{code}),920 .exited => |code| if (code != 0) eval.fatal("compiler failed with code {d}", .{code}),
920 .signal => |sig| eval.fatal("compiler terminated with signal {t}", .{sig}),921 .signal => |sig| eval.fatal("compiler terminated with signal {t}", .{sig}),
921 .stopped, .unknown => eval.fatal("compiler terminated unexpectedly", .{}),922 .stopped => |sig| eval.fatal("compiler stopped unexpectedly with signal {t}", .{sig}),
923 .unknown => eval.fatal("compiler terminated unexpectedly", .{}),
922 }924 }
923}925}
924926
tools/update_clang_options.zig+10-2
...@@ -688,9 +688,17 @@ pub fn main(init: std.process.Init) !void {...@@ -688,9 +688,17 @@ pub fn main(init: std.process.Init) !void {
688688
689 const json_text = switch (child_result.term) {689 const json_text = switch (child_result.term) {
690 .exited => |code| if (code == 0) child_result.stdout else {690 .exited => |code| if (code == 0) child_result.stdout else {
691 fatal("llvm-tblgen exited with code {d}", .{code});691 fatal("llvm-tblgen exited with code {d}\n", .{code});
692 },
693 .signal => |sig| {
694 fatal("llvm-tblgen terminated with signal {t}\n", .{sig});
695 },
696 .stopped => |sig| {
697 fatal("llvm-tblgen stopped with signal {d}\n", .{sig});
698 },
699 .unknown => {
700 fatal("llvm-tblgen crashed\n", .{});
692 },701 },
693 else => fatal("llvm-tblgen crashed", .{}),
694 };702 };
695703
696 const parsed = try json.parseFromSlice(json.Value, arena, json_text, .{});704 const parsed = try json.parseFromSlice(json.Value, arena, json_text, .{});
tools/update_cpu_features.zig+9-1
...@@ -2012,7 +2012,15 @@ fn processOneTarget(io: Io, job: Job) void {...@@ -2012,7 +2012,15 @@ fn processOneTarget(io: Io, job: Job) void {
2012 std.debug.print("llvm-tblgen exited with code {d}\n", .{code});2012 std.debug.print("llvm-tblgen exited with code {d}\n", .{code});
2013 std.process.exit(1);2013 std.process.exit(1);
2014 },2014 },
2015 else => {2015 .signal => |sig| {
2016 std.debug.print("llvm-tblgen terminated with signal {t}\n", .{sig});
2017 std.process.exit(1);
2018 },
2019 .stopped => |sig| {
2020 std.debug.print("llvm-tblgen stopped with signal {t}\n", .{sig});
2021 std.process.exit(1);
2022 },
2023 .unknown => {
2016 std.debug.print("llvm-tblgen crashed\n", .{});2024 std.debug.print("llvm-tblgen crashed\n", .{});
2017 std.process.exit(1);2025 std.process.exit(1);
2018 },2026 },