aboutsummaryrefslogtreecommitdiff
path: root/src/Compilation.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-12-10 17:43:42 -0800
committerAndrew Kelley <andrew@ziglang.org>2024-12-10 18:11:12 -0800
commitd37ee79535188263bd6a907eb26a48364c4c12f2 (patch)
tree9cff3c562afce6f3ddedfa236a7a819d92a9728a /src/Compilation.zig
parentc172877b81f4eff50cf214eb553c9df108fbd9eb (diff)
downloadzig-d37ee79535188263bd6a907eb26a48364c4c12f2.tar.gz
zig-d37ee79535188263bd6a907eb26a48364c4c12f2.zip
std.Build.Cache.hit: more discipline in error handling
Previous commits 2b0929929d67e222ca6a9523a3a594ed456c4a51 4ea2f441df36cec61e1017f4d795d4037326c98c had this text: > There are no dir components, so you would think that this was > unreachable, however we have observed on macOS two processes racing to > do openat() with O_CREAT manifest in ENOENT. This appears to have been a misunderstanding based on the issue report #12138 and corresponding PR #12139 in which the steps to reproduce removed the cache directory in a loop which also executed detached Zig compiler processes. There is no evidence for the macOS kernel bug however the ENOENT is easily explained by the removal of the cache directory. This commit reverts those commits, ultimately reporting the ENOENT as an error rather than repeating the create file operation. However this commit also adds an explicit error set to `std.Build.Cache.hit` as well as changing the `failed_file_index` to a proper diagnostic field that fully communicates what failed, leading to more informative error messages on failure to check the cache. The equivalent failure when occuring for AstGen performs a fatal process kill, reasoning being that the compiler has an invariant of the cache directory not being yanked out from underneath it while executing. This could be made a more granular error in the future but I suspect such thing is not valuable to pursue. Related to #18340 but does not solve it.
Diffstat (limited to 'src/Compilation.zig')
-rw-r--r--src/Compilation.zig31
1 files changed, 23 insertions, 8 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index c198b5af82..12e8a87831 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -2048,15 +2048,30 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
whole.cache_manifest = &man;
try addNonIncrementalStuffToCacheManifest(comp, arena, &man);
- const is_hit = man.hit() catch |err| {
- const i = man.failed_file_index orelse return err;
- const pp = man.files.keys()[i].prefixed_path;
- const prefix = man.cache.prefixes()[pp.prefix];
- return comp.setMiscFailure(
+ const is_hit = man.hit() catch |err| switch (err) {
+ error.CacheCheckFailed => switch (man.diagnostic) {
+ .none => unreachable,
+ .manifest_create, .manifest_read, .manifest_lock => |e| return comp.setMiscFailure(
+ .check_whole_cache,
+ "failed to check cache: {s} {s}",
+ .{ @tagName(man.diagnostic), @errorName(e) },
+ ),
+ .file_open, .file_stat, .file_read, .file_hash => |op| {
+ const pp = man.files.keys()[op.file_index].prefixed_path;
+ const prefix = man.cache.prefixes()[pp.prefix];
+ return comp.setMiscFailure(
+ .check_whole_cache,
+ "failed to check cache: '{}{s}' {s} {s}",
+ .{ prefix, pp.sub_path, @tagName(man.diagnostic), @errorName(op.err) },
+ );
+ },
+ },
+ error.OutOfMemory => return error.OutOfMemory,
+ error.InvalidFormat => return comp.setMiscFailure(
.check_whole_cache,
- "unable to check cache: stat file '{}{s}' failed: {s}",
- .{ prefix, pp.sub_path, @errorName(err) },
- );
+ "failed check cache: invalid manifest file format",
+ .{},
+ ),
};
if (is_hit) {
// In this case the cache hit contains the full set of file system inputs. Nice!