Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"error: failed to rename compilation results" when using zig build test --watch on Windows #21104

Open
kcbanner opened this issue Aug 17, 2024 · 4 comments
Labels
bug Observed behavior contradicts documented or intended behavior os-windows

Comments

@kcbanner
Copy link
Contributor

kcbanner commented Aug 17, 2024

Zig Version

0.14.0-dev.1077+9be10ea96

Steps to Reproduce and Observed Behavior

  1. zig init
  2. zig build test --watch
  3. Edit src/main.zig, comment line 24 (so the test fails)
  4. The watcher rebuilds it and the test fails
  5. Uncomment the line

Repeat steps 3-5 until the crash is observed - this takes around 3 tries for me (there must be a race condition somewhere in this logic):

error: failed to rename compilation results ('c:\cygwin64\home\kcbanner\temp\watch\.zig-cache\tmp\44b0a3ebbd5749a5') into local cache ('c:\cygwin64\home\kcbanner\temp\watch\.zig-cache\o\e5978ca4b34c31e02cb598792a99289d'): AccessDenied
error: the following command failed with 1 compilation errors:
C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\bin\zig.exe test -ODebug -Mroot=C:\cygwin64\home\kcbanner\temp\watch\src\main.zig --cache-dir c:\cygwin64\home\kcbanner\temp\watch\.zig-cache --global-cache-dir e:\dev\zig-cache --name test --zig-lib-dir C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\ --listen=-
Build Summary: 2/5 steps succeeded; 1 failed; 1/1 tests passed
test transitive failure
└─ run test transitive failure
   └─ zig test Debug native 1 errors
error.Unexpected: GetLastError(5): Access is denied.

C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\std\Build\Watch.zig:285:69: 0x2fa4b8 in startListening (build.exe.obj)
                        else => |err| return windows.unexpectedError(err),
                                                                    ^
C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\std\Build\Watch.zig:425:35: 0x300d9e in markDirtySteps (build.exe.obj)
            try dir.startListening();
                                  ^
C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\std\Build\Watch.zig:667:52: 0x301851 in wait (build.exe.obj)
                    break if (try Os.markDirtySteps(w, gpa, dir))
                                                   ^
C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\compiler\build_runner.zig:464:40: 0x306abf in main (build.exe.obj)
        while (true) switch (try w.wait(gpa, debounce_timeout)) {
                                       ^
C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\std\start.zig:442:53: 0x30cfd7 in WinStartup (build.exe.obj)
    std.os.windows.ntdll.RtlExitUserProcess(callMain());
                                                    ^
???:?:?: 0x7ffdd2187373 in ??? (KERNEL32.DLL)
???:?:?: 0x7ffdd309cc90 in ??? (ntdll.dll)
error: Unexpected
C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\std\os\windows.zig:2789:5: 0x2fa5bc in unexpectedError (build.exe.obj)
    return error.Unexpected;
    ^
C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\std\Build\Watch.zig:285:39: 0x2fa4c5 in startListening (build.exe.obj)
                        else => |err| return windows.unexpectedError(err),
                                      ^
C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\std\Build\Watch.zig:425:13: 0x3011bc in markDirtySteps (build.exe.obj)
            try dir.startListening();
            ^
C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\std\Build\Watch.zig:667:31: 0x301892 in wait (build.exe.obj)
                    break if (try Os.markDirtySteps(w, gpa, dir))
                              ^
C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\compiler\build_runner.zig:464:30: 0x306b08 in main (build.exe.obj)
        while (true) switch (try w.wait(gpa, debounce_timeout)) {
                             ^
error: the following build command failed with exit code 1:
c:\cygwin64\home\kcbanner\temp\watch\.zig-cache\o\2a5397fa816ba930eaa2dcbaa4a553c9\build.exe C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\bin\zig.exe C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig c:\cygwin64\home\kcbanner\temp\watch c:\cygwin64\home\kcbanner\temp\watch\.zig-cache e:\dev\zig-cache --seed 0x4e66927e -Zc3905d7c88a20ee8 test --watch

Expected Behavior

The watcher should remain alive without crashing.

@kcbanner kcbanner added the bug Observed behavior contradicts documented or intended behavior label Aug 17, 2024
@squeek502
Copy link
Collaborator

cc @jayrod246 (the version in the OP includes #20907 btw)

@jayrod246
Copy link
Contributor

jayrod246 commented Aug 19, 2024

I placed this code at line 466 in Watch.zig:

for (files.items) |basename| {
    const tmp = try path.joinString(gpa, basename);
    defer gpa.free(tmp);
    path.access(basename, .{}) catch {
        std.debug.print("\n*****************\nFILE MISSING: {s}\n*****************\n", .{tmp});
    };
    const gop = try reaction_set.getOrPut(gpa, basename);
    if (!gop.found_existing) gop.value_ptr.* = .{};
    try gop.value_ptr.put(gpa, step, w.generation);
}

and repeating your steps I eventually get:

*****************
FILE MISSING: C:\Dev\watch-test\.zig-cache\o\356a82588c29f2bf10b5221a7f14b907\test.exe
*****************

At this point, the file test.exe which is an input to some step, gets marked as "persisted". But since that file doesn’t exist, and from what I could tell the parent directory no longer exists either, we get the access denied. I want to guess that the problem stems from somewhere else in the build system? (the input files comes from a Step’s inputs, which are passed in from outside Watch.zig)

@jayrod246
Copy link
Contributor

jayrod246 commented Aug 20, 2024

This might have more to do with #20631 as I noticed we are attempting to watch directories inside .zig-cache/o/.

test.exe is an artifact, which Watch.zig is attempting to track. But the Run step that depends on the artifact should have been invalidated already by the source files from which the artifact is built.

The solution I suppose is to avoid watching artifact directories, which in turn should avoid the AccessDenied error. (which I assume is caused by the Watch.zig file handle we have open on it)

@kcbanner
Copy link
Contributor Author

Interesting, yea that does seem to be the cause. Thanks for looking into this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior os-windows
Projects
None yet
Development

No branches or pull requests

3 participants