authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-03-27 05:08:24-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-03-27 18:06:08+01:00
logb490412cd28e4bc76de9dfe39ac1d99435a86814
tree68ac20fbe62261e8c522353299afe8d7b657b4f9
parent523cfabcdff65c9547299b3a4f721d2052c163ee

build runner: fail, not warn when insufficient memory

Users can proceed by telling the build system how much memory to assume the system has. I have improved the failure message to communicate this. Partially reverts 87f8f47ba508b684d03c13b850cac3fb72efac26 Even if we wanted to unrevert this reverted commit, it's not sufficient to merely downgrade the failure to a warning, because the main scheduling logic will fail to schedule steps that have a max_rss exceeding the detected system value, causing some steps to never get executed, eventually tripping an assert. Such a change would need to also override the max_rss value to be equal to the greatest value across all steps. closes #31510

1 files changed, 10 insertions(+), 5 deletions(-)

lib/compiler/build_runner.zig+10-5
...@@ -532,7 +532,7 @@ pub fn main(init: process.Init.Minimal) !void {...@@ -532,7 +532,7 @@ pub fn main(init: process.Init.Minimal) !void {
532 }532 }
533533
534 prepare(arena, builder, targets.items, &run, graph.random_seed) catch |err| switch (err) {534 prepare(arena, builder, targets.items, &run, graph.random_seed) catch |err| switch (err) {
535 error.DependencyLoopDetected => {535 error.DependencyLoopDetected, error.InsufficientMemory => {
536 // Perhaps in the future there could be an Advanced Options flag536 // Perhaps in the future there could be an Advanced Options flag
537 // such as --debug-build-runner-leaks which would make this code537 // such as --debug-build-runner-leaks which would make this code
538 // return instead of calling exit.538 // return instead of calling exit.
...@@ -696,8 +696,8 @@ fn prepare(...@@ -696,8 +696,8 @@ fn prepare(
696 for (0..step_names.len) |i| {696 for (0..step_names.len) |i| {
697 const step_name = step_names[step_names.len - i - 1];697 const step_name = step_names[step_names.len - i - 1];
698 const s = b.top_level_steps.get(step_name) orelse {698 const s = b.top_level_steps.get(step_name) orelse {
699 std.debug.print("no step named '{s}'\n access the help menu with 'zig build -h'\n", .{step_name});699 std.log.info("access the help menu with \"zig build -h\"", .{});
700 process.exit(1);700 fatal("no step named '{s}'", .{step_name});
701 };701 };
702 step_stack.putAssumeCapacity(&s.step, {});702 step_stack.putAssumeCapacity(&s.step, {});
703 }703 }
...@@ -716,8 +716,10 @@ fn prepare(...@@ -716,8 +716,10 @@ fn prepare(
716 {716 {
717 // Check that we have enough memory to complete the build.717 // Check that we have enough memory to complete the build.
718 var any_problems = false;718 var any_problems = false;
719 var max_needed: usize = 0;
719 for (step_stack.keys()) |s| {720 for (step_stack.keys()) |s| {
720 if (s.max_rss == 0) continue;721 if (s.max_rss == 0) continue;
722 max_needed = @max(max_needed, s.max_rss);
721 if (s.max_rss > run.available_rss) {723 if (s.max_rss > run.available_rss) {
722 if (run.skip_oom_steps) {724 if (run.skip_oom_steps) {
723 s.state = .skipped_oom;725 s.state = .skipped_oom;
...@@ -725,7 +727,7 @@ fn prepare(...@@ -725,7 +727,7 @@ fn prepare(
725 dependant.pending_deps -= 1;727 dependant.pending_deps -= 1;
726 }728 }
727 } else {729 } else {
728 std.debug.print("{s}{s}: this step declares an upper bound of {d} bytes of memory, exceeding the available {d} bytes of memory\n", .{730 std.log.err("{s}{s}: this step declares an upper bound of {d} bytes of memory, exceeding the available {d} bytes of memory", .{
729 s.owner.dep_prefix, s.name, s.max_rss, run.available_rss,731 s.owner.dep_prefix, s.name, s.max_rss, run.available_rss,
730 });732 });
731 any_problems = true;733 any_problems = true;
...@@ -734,8 +736,11 @@ fn prepare(...@@ -734,8 +736,11 @@ fn prepare(
734 }736 }
735 if (any_problems) {737 if (any_problems) {
736 if (run.max_rss_is_default) {738 if (run.max_rss_is_default) {
737 std.debug.print("note: use --maxrss to override the default", .{});739 std.log.info("use --maxrss {d} to proceed, risking system memory exhaustion", .{
740 max_needed,
741 });
738 }742 }
743 return error.InsufficientMemory;
739 }744 }
740 }745 }
741}746}