| author | |
| committer | |
| log | 7dd4afb224f4ca747b8eb462c28337ce9a63d38c |
| tree | e4e634ad79891ae089b7f02f417bf661824f6679 |
| parent | 4592fd26b937d8c7ff91295408d8377c1c13cf53 |
passthrough mode does not mean always exit - it just means to pass
through stdio and exit if the child process exits, without doing any
special error reporting.5 files changed, 193 insertions(+), 137 deletions(-)
src/Compilation.zig+1-1| ... | @@ -1804,7 +1804,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: * | ... | @@ -1804,7 +1804,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: * |
| 1804 | if (comp.clang_preprocessor_mode == .stdout) | 1804 | if (comp.clang_preprocessor_mode == .stdout) |
| 1805 | std.process.exit(0); | 1805 | std.process.exit(0); |
| 1806 | }, | 1806 | }, |
| 1807 | else => std.process.exit(1), | 1807 | else => std.process.abort(), |
| 1808 | } | 1808 | } |
| 1809 | } else { | 1809 | } else { |
| 1810 | child.stdin_behavior = .Ignore; | 1810 | child.stdin_behavior = .Ignore; |
src/link/Coff.zig+50-36| ... | @@ -1153,46 +1153,60 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { | ... | @@ -1153,46 +1153,60 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 1153 | } | 1153 | } |
| 1154 | 1154 | ||
| 1155 | // Sadly, we must run LLD as a child process because it does not behave | 1155 | // Sadly, we must run LLD as a child process because it does not behave |
| 1156 | // properly as a library. One exception is if we are running in passthrough | 1156 | // properly as a library. |
| 1157 | // mode, which means Clang / LLD should inherit stdio and are allowed to | ||
| 1158 | // crash zig directly. | ||
| 1159 | if (comp.clang_passthrough_mode) { | ||
| 1160 | return @import("../main.zig").punt_to_lld(arena, argv.items); | ||
| 1161 | } | ||
| 1162 | |||
| 1163 | const child = try std.ChildProcess.init(argv.items, arena); | 1157 | const child = try std.ChildProcess.init(argv.items, arena); |
| 1164 | defer child.deinit(); | 1158 | defer child.deinit(); |
| 1165 | 1159 | ||
| 1166 | child.stdin_behavior = .Ignore; | 1160 | if (comp.clang_passthrough_mode) { |
| 1167 | child.stdout_behavior = .Ignore; | 1161 | child.stdin_behavior = .Inherit; |
| 1168 | child.stderr_behavior = .Pipe; | 1162 | child.stdout_behavior = .Inherit; |
| 1169 | 1163 | child.stderr_behavior = .Inherit; | |
| 1170 | try child.spawn(); | 1164 | |
| 1171 | 1165 | const term = child.spawnAndWait() catch |err| { | |
| 1172 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); | 1166 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); |
| 1173 | 1167 | return error.UnableToSpawnSelf; | |
| 1174 | const term = child.wait() catch |err| { | 1168 | }; |
| 1175 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | 1169 | switch (term) { |
| 1176 | return error.UnableToSpawnSelf; | 1170 | .Exited => |code| { |
| 1177 | }; | 1171 | if (code != 0) { |
| 1178 | 1172 | // TODO https://github.com/ziglang/zig/issues/6342 | |
| 1179 | switch (term) { | 1173 | std.process.exit(1); |
| 1180 | .Exited => |code| { | 1174 | } |
| 1181 | if (code != 0) { | 1175 | }, |
| 1182 | // TODO parse this output and surface with the Compilation API rather than | 1176 | else => std.process.abort(), |
| 1183 | // directly outputting to stderr here. | 1177 | } |
| 1184 | std.debug.print("{s}", .{stderr}); | 1178 | } else { |
| 1185 | return error.LLDReportedFailure; | 1179 | child.stdin_behavior = .Ignore; |
| 1186 | } | 1180 | child.stdout_behavior = .Ignore; |
| 1187 | }, | 1181 | child.stderr_behavior = .Pipe; |
| 1188 | else => { | 1182 | |
| 1189 | log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr }); | 1183 | try child.spawn(); |
| 1190 | return error.LLDCrashed; | 1184 | |
| 1191 | }, | 1185 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); |
| 1192 | } | 1186 | |
| 1187 | const term = child.wait() catch |err| { | ||
| 1188 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | ||
| 1189 | return error.UnableToSpawnSelf; | ||
| 1190 | }; | ||
| 1191 | |||
| 1192 | switch (term) { | ||
| 1193 | .Exited => |code| { | ||
| 1194 | if (code != 0) { | ||
| 1195 | // TODO parse this output and surface with the Compilation API rather than | ||
| 1196 | // directly outputting to stderr here. | ||
| 1197 | std.debug.print("{s}", .{stderr}); | ||
| 1198 | return error.LLDReportedFailure; | ||
| 1199 | } | ||
| 1200 | }, | ||
| 1201 | else => { | ||
| 1202 | log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr }); | ||
| 1203 | return error.LLDCrashed; | ||
| 1204 | }, | ||
| 1205 | } | ||
| 1193 | 1206 | ||
| 1194 | if (stderr.len != 0) { | 1207 | if (stderr.len != 0) { |
| 1195 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); | 1208 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); |
| 1209 | } | ||
| 1196 | } | 1210 | } |
| 1197 | } | 1211 | } |
| 1198 | 1212 |
src/link/Elf.zig+46-32| ... | @@ -1632,46 +1632,60 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1632,46 +1632,60 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1632 | } | 1632 | } |
| 1633 | 1633 | ||
| 1634 | // Sadly, we must run LLD as a child process because it does not behave | 1634 | // Sadly, we must run LLD as a child process because it does not behave |
| 1635 | // properly as a library. One exception is if we are running in passthrough | 1635 | // properly as a library. |
| 1636 | // mode, which means Clang / LLD should inherit stdio and are allowed to | ||
| 1637 | // crash zig directly. | ||
| 1638 | if (comp.clang_passthrough_mode) { | ||
| 1639 | return @import("../main.zig").punt_to_lld(arena, argv.items); | ||
| 1640 | } | ||
| 1641 | |||
| 1642 | const child = try std.ChildProcess.init(argv.items, arena); | 1636 | const child = try std.ChildProcess.init(argv.items, arena); |
| 1643 | defer child.deinit(); | 1637 | defer child.deinit(); |
| 1644 | 1638 | ||
| 1645 | child.stdin_behavior = .Ignore; | 1639 | if (comp.clang_passthrough_mode) { |
| 1646 | child.stdout_behavior = .Ignore; | 1640 | child.stdin_behavior = .Inherit; |
| 1647 | child.stderr_behavior = .Pipe; | 1641 | child.stdout_behavior = .Inherit; |
| 1642 | child.stderr_behavior = .Inherit; | ||
| 1648 | 1643 | ||
| 1649 | try child.spawn(); | 1644 | const term = child.spawnAndWait() catch |err| { |
| 1645 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | ||
| 1646 | return error.UnableToSpawnSelf; | ||
| 1647 | }; | ||
| 1648 | switch (term) { | ||
| 1649 | .Exited => |code| { | ||
| 1650 | if (code != 0) { | ||
| 1651 | // TODO https://github.com/ziglang/zig/issues/6342 | ||
| 1652 | std.process.exit(1); | ||
| 1653 | } | ||
| 1654 | }, | ||
| 1655 | else => std.process.abort(), | ||
| 1656 | } | ||
| 1657 | } else { | ||
| 1658 | child.stdin_behavior = .Ignore; | ||
| 1659 | child.stdout_behavior = .Ignore; | ||
| 1660 | child.stderr_behavior = .Pipe; | ||
| 1650 | 1661 | ||
| 1651 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); | 1662 | try child.spawn(); |
| 1652 | 1663 | ||
| 1653 | const term = child.wait() catch |err| { | 1664 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); |
| 1654 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | ||
| 1655 | return error.UnableToSpawnSelf; | ||
| 1656 | }; | ||
| 1657 | 1665 | ||
| 1658 | switch (term) { | 1666 | const term = child.wait() catch |err| { |
| 1659 | .Exited => |code| { | 1667 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); |
| 1660 | if (code != 0) { | 1668 | return error.UnableToSpawnSelf; |
| 1661 | // TODO parse this output and surface with the Compilation API rather than | 1669 | }; |
| 1662 | // directly outputting to stderr here. | ||
| 1663 | std.debug.print("{s}", .{stderr}); | ||
| 1664 | return error.LLDReportedFailure; | ||
| 1665 | } | ||
| 1666 | }, | ||
| 1667 | else => { | ||
| 1668 | log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr }); | ||
| 1669 | return error.LLDCrashed; | ||
| 1670 | }, | ||
| 1671 | } | ||
| 1672 | 1670 | ||
| 1673 | if (stderr.len != 0) { | 1671 | switch (term) { |
| 1674 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); | 1672 | .Exited => |code| { |
| 1673 | if (code != 0) { | ||
| 1674 | // TODO parse this output and surface with the Compilation API rather than | ||
| 1675 | // directly outputting to stderr here. | ||
| 1676 | std.debug.print("{s}", .{stderr}); | ||
| 1677 | return error.LLDReportedFailure; | ||
| 1678 | } | ||
| 1679 | }, | ||
| 1680 | else => { | ||
| 1681 | log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr }); | ||
| 1682 | return error.LLDCrashed; | ||
| 1683 | }, | ||
| 1684 | } | ||
| 1685 | |||
| 1686 | if (stderr.len != 0) { | ||
| 1687 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); | ||
| 1688 | } | ||
| 1675 | } | 1689 | } |
| 1676 | 1690 | ||
| 1677 | if (!self.base.options.disable_lld_caching) { | 1691 | if (!self.base.options.disable_lld_caching) { |
src/link/MachO.zig+50-36| ... | @@ -686,46 +686,60 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { | ... | @@ -686,46 +686,60 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { |
| 686 | } | 686 | } |
| 687 | } else { | 687 | } else { |
| 688 | // Sadly, we must run LLD as a child process because it does not behave | 688 | // Sadly, we must run LLD as a child process because it does not behave |
| 689 | // properly as a library. One exception is if we are running in passthrough | 689 | // properly as a library. |
| 690 | // mode, which means Clang / LLD should inherit stdio and are allowed to | ||
| 691 | // crash zig directly. | ||
| 692 | if (comp.clang_passthrough_mode) { | ||
| 693 | return @import("../main.zig").punt_to_lld(arena, argv.items); | ||
| 694 | } | ||
| 695 | |||
| 696 | const child = try std.ChildProcess.init(argv.items, arena); | 690 | const child = try std.ChildProcess.init(argv.items, arena); |
| 697 | defer child.deinit(); | 691 | defer child.deinit(); |
| 698 | 692 | ||
| 699 | child.stdin_behavior = .Ignore; | 693 | if (comp.clang_passthrough_mode) { |
| 700 | child.stdout_behavior = .Ignore; | 694 | child.stdin_behavior = .Inherit; |
| 701 | child.stderr_behavior = .Pipe; | 695 | child.stdout_behavior = .Inherit; |
| 702 | 696 | child.stderr_behavior = .Inherit; | |
| 703 | try child.spawn(); | 697 | |
| 704 | 698 | const term = child.spawnAndWait() catch |err| { | |
| 705 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); | 699 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); |
| 706 | 700 | return error.UnableToSpawnSelf; | |
| 707 | const term = child.wait() catch |err| { | 701 | }; |
| 708 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | 702 | switch (term) { |
| 709 | return error.UnableToSpawnSelf; | 703 | .Exited => |code| { |
| 710 | }; | 704 | if (code != 0) { |
| 711 | 705 | // TODO https://github.com/ziglang/zig/issues/6342 | |
| 712 | switch (term) { | 706 | std.process.exit(1); |
| 713 | .Exited => |code| { | 707 | } |
| 714 | if (code != 0) { | 708 | }, |
| 715 | // TODO parse this output and surface with the Compilation API rather than | 709 | else => std.process.abort(), |
| 716 | // directly outputting to stderr here. | 710 | } |
| 717 | std.debug.print("{s}", .{stderr}); | 711 | } else { |
| 718 | return error.LLDReportedFailure; | 712 | child.stdin_behavior = .Ignore; |
| 719 | } | 713 | child.stdout_behavior = .Ignore; |
| 720 | }, | 714 | child.stderr_behavior = .Pipe; |
| 721 | else => { | 715 | |
| 722 | log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr }); | 716 | try child.spawn(); |
| 723 | return error.LLDCrashed; | 717 | |
| 724 | }, | 718 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); |
| 725 | } | 719 | |
| 720 | const term = child.wait() catch |err| { | ||
| 721 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | ||
| 722 | return error.UnableToSpawnSelf; | ||
| 723 | }; | ||
| 724 | |||
| 725 | switch (term) { | ||
| 726 | .Exited => |code| { | ||
| 727 | if (code != 0) { | ||
| 728 | // TODO parse this output and surface with the Compilation API rather than | ||
| 729 | // directly outputting to stderr here. | ||
| 730 | std.debug.print("{s}", .{stderr}); | ||
| 731 | return error.LLDReportedFailure; | ||
| 732 | } | ||
| 733 | }, | ||
| 734 | else => { | ||
| 735 | log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr }); | ||
| 736 | return error.LLDCrashed; | ||
| 737 | }, | ||
| 738 | } | ||
| 726 | 739 | ||
| 727 | if (stderr.len != 0) { | 740 | if (stderr.len != 0) { |
| 728 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); | 741 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); |
| 742 | } | ||
| 729 | } | 743 | } |
| 730 | 744 | ||
| 731 | // At this stage, LLD has done its job. It is time to patch the resultant | 745 | // At this stage, LLD has done its job. It is time to patch the resultant |
src/link/Wasm.zig+46-32| ... | @@ -403,46 +403,60 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { | ... | @@ -403,46 +403,60 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | // Sadly, we must run LLD as a child process because it does not behave | 405 | // Sadly, we must run LLD as a child process because it does not behave |
| 406 | // properly as a library. One exception is if we are running in passthrough | 406 | // properly as a library. |
| 407 | // mode, which means Clang / LLD should inherit stdio and are allowed to | ||
| 408 | // crash zig directly. | ||
| 409 | if (comp.clang_passthrough_mode) { | ||
| 410 | return @import("../main.zig").punt_to_lld(arena, argv.items); | ||
| 411 | } | ||
| 412 | |||
| 413 | const child = try std.ChildProcess.init(argv.items, arena); | 407 | const child = try std.ChildProcess.init(argv.items, arena); |
| 414 | defer child.deinit(); | 408 | defer child.deinit(); |
| 415 | 409 | ||
| 416 | child.stdin_behavior = .Ignore; | 410 | if (comp.clang_passthrough_mode) { |
| 417 | child.stdout_behavior = .Ignore; | 411 | child.stdin_behavior = .Inherit; |
| 418 | child.stderr_behavior = .Pipe; | 412 | child.stdout_behavior = .Inherit; |
| 413 | child.stderr_behavior = .Inherit; | ||
| 419 | 414 | ||
| 420 | try child.spawn(); | 415 | const term = child.spawnAndWait() catch |err| { |
| 416 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | ||
| 417 | return error.UnableToSpawnSelf; | ||
| 418 | }; | ||
| 419 | switch (term) { | ||
| 420 | .Exited => |code| { | ||
| 421 | if (code != 0) { | ||
| 422 | // TODO https://github.com/ziglang/zig/issues/6342 | ||
| 423 | std.process.exit(1); | ||
| 424 | } | ||
| 425 | }, | ||
| 426 | else => std.process.abort(), | ||
| 427 | } | ||
| 428 | } else { | ||
| 429 | child.stdin_behavior = .Ignore; | ||
| 430 | child.stdout_behavior = .Ignore; | ||
| 431 | child.stderr_behavior = .Pipe; | ||
| 421 | 432 | ||
| 422 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); | 433 | try child.spawn(); |
| 423 | 434 | ||
| 424 | const term = child.wait() catch |err| { | 435 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); |
| 425 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | ||
| 426 | return error.UnableToSpawnSelf; | ||
| 427 | }; | ||
| 428 | 436 | ||
| 429 | switch (term) { | 437 | const term = child.wait() catch |err| { |
| 430 | .Exited => |code| { | 438 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); |
| 431 | if (code != 0) { | 439 | return error.UnableToSpawnSelf; |
| 432 | // TODO parse this output and surface with the Compilation API rather than | 440 | }; |
| 433 | // directly outputting to stderr here. | ||
| 434 | std.debug.print("{s}", .{stderr}); | ||
| 435 | return error.LLDReportedFailure; | ||
| 436 | } | ||
| 437 | }, | ||
| 438 | else => { | ||
| 439 | log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr }); | ||
| 440 | return error.LLDCrashed; | ||
| 441 | }, | ||
| 442 | } | ||
| 443 | 441 | ||
| 444 | if (stderr.len != 0) { | 442 | switch (term) { |
| 445 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); | 443 | .Exited => |code| { |
| 444 | if (code != 0) { | ||
| 445 | // TODO parse this output and surface with the Compilation API rather than | ||
| 446 | // directly outputting to stderr here. | ||
| 447 | std.debug.print("{s}", .{stderr}); | ||
| 448 | return error.LLDReportedFailure; | ||
| 449 | } | ||
| 450 | }, | ||
| 451 | else => { | ||
| 452 | log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr }); | ||
| 453 | return error.LLDCrashed; | ||
| 454 | }, | ||
| 455 | } | ||
| 456 | |||
| 457 | if (stderr.len != 0) { | ||
| 458 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); | ||
| 459 | } | ||
| 446 | } | 460 | } |
| 447 | 461 | ||
| 448 | if (!self.base.options.disable_lld_caching) { | 462 | if (!self.base.options.disable_lld_caching) { |