| 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 | 1804 | if (comp.clang_preprocessor_mode == .stdout) |
| 1805 | 1805 | std.process.exit(0); |
| 1806 | 1806 | }, |
| 1807 | else => std.process.exit(1), | |
| 1807 | else => std.process.abort(), | |
| 1808 | 1808 | } |
| 1809 | 1809 | } else { |
| 1810 | 1810 | child.stdin_behavior = .Ignore; |
src/link/Coff.zig+50-36| ... | ... | @@ -1153,46 +1153,60 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 1153 | 1153 | } |
| 1154 | 1154 | |
| 1155 | 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 | |
| 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 | ||
| 1156 | // properly as a library. | |
| 1163 | 1157 | const child = try std.ChildProcess.init(argv.items, arena); |
| 1164 | 1158 | defer child.deinit(); |
| 1165 | 1159 | |
| 1166 | child.stdin_behavior = .Ignore; | |
| 1167 | child.stdout_behavior = .Ignore; | |
| 1168 | child.stderr_behavior = .Pipe; | |
| 1169 | ||
| 1170 | try child.spawn(); | |
| 1171 | ||
| 1172 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); | |
| 1173 | ||
| 1174 | const term = child.wait() catch |err| { | |
| 1175 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | |
| 1176 | return error.UnableToSpawnSelf; | |
| 1177 | }; | |
| 1178 | ||
| 1179 | switch (term) { | |
| 1180 | .Exited => |code| { | |
| 1181 | if (code != 0) { | |
| 1182 | // TODO parse this output and surface with the Compilation API rather than | |
| 1183 | // directly outputting to stderr here. | |
| 1184 | std.debug.print("{s}", .{stderr}); | |
| 1185 | return error.LLDReportedFailure; | |
| 1186 | } | |
| 1187 | }, | |
| 1188 | else => { | |
| 1189 | log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr }); | |
| 1190 | return error.LLDCrashed; | |
| 1191 | }, | |
| 1192 | } | |
| 1160 | if (comp.clang_passthrough_mode) { | |
| 1161 | child.stdin_behavior = .Inherit; | |
| 1162 | child.stdout_behavior = .Inherit; | |
| 1163 | child.stderr_behavior = .Inherit; | |
| 1164 | ||
| 1165 | const term = child.spawnAndWait() catch |err| { | |
| 1166 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | |
| 1167 | return error.UnableToSpawnSelf; | |
| 1168 | }; | |
| 1169 | switch (term) { | |
| 1170 | .Exited => |code| { | |
| 1171 | if (code != 0) { | |
| 1172 | // TODO https://github.com/ziglang/zig/issues/6342 | |
| 1173 | std.process.exit(1); | |
| 1174 | } | |
| 1175 | }, | |
| 1176 | else => std.process.abort(), | |
| 1177 | } | |
| 1178 | } else { | |
| 1179 | child.stdin_behavior = .Ignore; | |
| 1180 | child.stdout_behavior = .Ignore; | |
| 1181 | child.stderr_behavior = .Pipe; | |
| 1182 | ||
| 1183 | try child.spawn(); | |
| 1184 | ||
| 1185 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); | |
| 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) { | |
| 1195 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); | |
| 1207 | if (stderr.len != 0) { | |
| 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 | 1632 | } |
| 1633 | 1633 | |
| 1634 | 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 | |
| 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 | ||
| 1635 | // properly as a library. | |
| 1642 | 1636 | const child = try std.ChildProcess.init(argv.items, arena); |
| 1643 | 1637 | defer child.deinit(); |
| 1644 | 1638 | |
| 1645 | child.stdin_behavior = .Ignore; | |
| 1646 | child.stdout_behavior = .Ignore; | |
| 1647 | child.stderr_behavior = .Pipe; | |
| 1639 | if (comp.clang_passthrough_mode) { | |
| 1640 | child.stdin_behavior = .Inherit; | |
| 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| { | |
| 1654 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | |
| 1655 | return error.UnableToSpawnSelf; | |
| 1656 | }; | |
| 1664 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); | |
| 1657 | 1665 | |
| 1658 | switch (term) { | |
| 1659 | .Exited => |code| { | |
| 1660 | if (code != 0) { | |
| 1661 | // TODO parse this output and surface with the Compilation API rather than | |
| 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 | } | |
| 1666 | const term = child.wait() catch |err| { | |
| 1667 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | |
| 1668 | return error.UnableToSpawnSelf; | |
| 1669 | }; | |
| 1672 | 1670 | |
| 1673 | if (stderr.len != 0) { | |
| 1674 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); | |
| 1671 | switch (term) { | |
| 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 | 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 | 686 | } |
| 687 | 687 | } else { |
| 688 | 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 | |
| 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 | ||
| 689 | // properly as a library. | |
| 696 | 690 | const child = try std.ChildProcess.init(argv.items, arena); |
| 697 | 691 | defer child.deinit(); |
| 698 | 692 | |
| 699 | child.stdin_behavior = .Ignore; | |
| 700 | child.stdout_behavior = .Ignore; | |
| 701 | child.stderr_behavior = .Pipe; | |
| 702 | ||
| 703 | try child.spawn(); | |
| 704 | ||
| 705 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); | |
| 706 | ||
| 707 | const term = child.wait() catch |err| { | |
| 708 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | |
| 709 | return error.UnableToSpawnSelf; | |
| 710 | }; | |
| 711 | ||
| 712 | switch (term) { | |
| 713 | .Exited => |code| { | |
| 714 | if (code != 0) { | |
| 715 | // TODO parse this output and surface with the Compilation API rather than | |
| 716 | // directly outputting to stderr here. | |
| 717 | std.debug.print("{s}", .{stderr}); | |
| 718 | return error.LLDReportedFailure; | |
| 719 | } | |
| 720 | }, | |
| 721 | else => { | |
| 722 | log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr }); | |
| 723 | return error.LLDCrashed; | |
| 724 | }, | |
| 725 | } | |
| 693 | if (comp.clang_passthrough_mode) { | |
| 694 | child.stdin_behavior = .Inherit; | |
| 695 | child.stdout_behavior = .Inherit; | |
| 696 | child.stderr_behavior = .Inherit; | |
| 697 | ||
| 698 | const term = child.spawnAndWait() catch |err| { | |
| 699 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | |
| 700 | return error.UnableToSpawnSelf; | |
| 701 | }; | |
| 702 | switch (term) { | |
| 703 | .Exited => |code| { | |
| 704 | if (code != 0) { | |
| 705 | // TODO https://github.com/ziglang/zig/issues/6342 | |
| 706 | std.process.exit(1); | |
| 707 | } | |
| 708 | }, | |
| 709 | else => std.process.abort(), | |
| 710 | } | |
| 711 | } else { | |
| 712 | child.stdin_behavior = .Ignore; | |
| 713 | child.stdout_behavior = .Ignore; | |
| 714 | child.stderr_behavior = .Pipe; | |
| 715 | ||
| 716 | try child.spawn(); | |
| 717 | ||
| 718 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); | |
| 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) { | |
| 728 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); | |
| 740 | if (stderr.len != 0) { | |
| 741 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); | |
| 742 | } | |
| 729 | 743 | } |
| 730 | 744 | |
| 731 | 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 | 403 | } |
| 404 | 404 | |
| 405 | 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 | |
| 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 | ||
| 406 | // properly as a library. | |
| 413 | 407 | const child = try std.ChildProcess.init(argv.items, arena); |
| 414 | 408 | defer child.deinit(); |
| 415 | 409 | |
| 416 | child.stdin_behavior = .Ignore; | |
| 417 | child.stdout_behavior = .Ignore; | |
| 418 | child.stderr_behavior = .Pipe; | |
| 410 | if (comp.clang_passthrough_mode) { | |
| 411 | child.stdin_behavior = .Inherit; | |
| 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| { | |
| 425 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | |
| 426 | return error.UnableToSpawnSelf; | |
| 427 | }; | |
| 435 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024); | |
| 428 | 436 | |
| 429 | switch (term) { | |
| 430 | .Exited => |code| { | |
| 431 | if (code != 0) { | |
| 432 | // TODO parse this output and surface with the Compilation API rather than | |
| 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 | } | |
| 437 | const term = child.wait() catch |err| { | |
| 438 | log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) }); | |
| 439 | return error.UnableToSpawnSelf; | |
| 440 | }; | |
| 443 | 441 | |
| 444 | if (stderr.len != 0) { | |
| 445 | std.log.warn("unexpected LLD stderr:\n{s}", .{stderr}); | |
| 442 | switch (term) { | |
| 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 | 462 | if (!self.base.options.disable_lld_caching) { |