excubo-ag / WebCompiler

Apache License 2.0
149 stars 30 forks source link

The command dotnet webcompiler exited with code 134. #25

Closed mikes-gh closed 1 year ago

mikes-gh commented 3 years ago

https://github.com/Garderoben/MudBlazor/pull/872/checks?check_run_id=1895540096

We are getting these regularly. Both on 2.6.2 and 2.6.4

stefanloerwald commented 3 years ago

Hi @mikes-gh,

this is not much information to go by. I went into the Azure pipeline log and noticed the exception. I don't see any reason why this exception should be thrown, so I added some more logging into v2.6.5. Please try that version and post any error output here, if available.

BR Stefan

mikes-gh commented 3 years ago

Yeh sorry I know its not much to go on but its all I have. Will try 2.6.5. The build pipeline did have both netcore 3.1 and net5 for dual targeting. Would that be an issue?

mikes-gh commented 3 years ago

https://dev.azure.com/gardnet-nu/MudBlazor/_build/results?buildId=2084&view=logs&j=00e998c7-699d-5986-d1da-f0168a6a583e&t=5fc2e39e-9cfc-589e-d57b-ed573899944d&l=22 failed build but it only seems to be for tests. No more logs seem to be generated. As you can see I am running 2.6.5

stefanloerwald commented 3 years ago

The logs are written to stderr, see https://github.com/excubo-ag/WebCompiler/blob/3b7e2a6f9dec46fc2269edb39851ab4f1d4330f1/WebCompiler/Program.cs#L268

The missing logs are probably because of the settings in your csproj file: https://github.com/Garderoben/MudBlazor/blob/master/src/MudBlazor/MudBlazor.csproj#L78 There's probably a similar setting for stderr, I'd guess StandardErrorImportance="high"

stefanloerwald commented 3 years ago

There's probably a similar setting for stderr, I'd guess StandardErrorImportance="high"

There is, and the guidance in this repo's README is now updated accordingly.

mikes-gh commented 3 years ago

OK Done will report back when it break again.

mikes-gh commented 3 years ago

Its also exiting with code 1

stefanloerwald commented 3 years ago

Its also exiting with code 1

That is expected: Before v2.6.5, there was an exception terminating the program. Now we catch exceptions and log them as errors.

mikes-gh commented 3 years ago

Hi Stefan I just received an error today https://dev.azure.com/gardnet-nu/MudBlazor/_build/results?buildId=2116&view=logs&j=00e998c7-699d-5986-d1da-f0168a6a583e&t=5fc2e39e-9cfc-589e-d57b-ed573899944d&l=22

stefanloerwald commented 3 years ago

Hi Mike,

just a note for the future: please copy the logs directly into the issue. I'm not a huge fan of browsing through the pipeline logs to find the relevant part for this project.

So this is the log for webcompiler:

A compilation step encountered an exception Could not find file '/home/vsts/work/1/s/src/MudBlazor/Styles/MudBlazor.min.css'. with stacktrace:
     at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
     at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
     at System.IO.FileStream.OpenHandle(FileMode mode, FileShare share, FileOptions options)
     at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
     at System.IO.File.ReadAllBytes(String path)
     at WebCompiler.Compile.Place.Compile(List`1 file_sequence) in /home/runner/work/WebCompiler/WebCompiler/WebCompiler/Compile/Place.cs:line 49
     at WebCompiler.Compile.CompilationStep.With(Compiler compiler) in /home/runner/work/WebCompiler/WebCompiler/WebCompiler/Compile/CompilationStep.cs:line 22

  The internal compiler Place encountered an exception: Could not find file '/home/vsts/work/1/s/src/MudBlazor/Styles/MudBlazor.min.css'.. 
  The stacktrace was:
     at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
     at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
     at System.IO.FileStream.OpenHandle(FileMode mode, FileShare share, FileOptions options)
     at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
     at System.IO.File.ReadAllBytes(String path)
     at WebCompiler.Compile.Place.Compile(List`1 file_sequence) in /home/runner/work/WebCompiler/WebCompiler/WebCompiler/Compile/Place.cs:line 49
     at WebCompiler.Compile.CompilationStep.With(Compiler compiler) in /home/runner/work/WebCompiler/WebCompiler/WebCompiler/Compile/CompilationStep.cs:line 22
  The state before this operations looked like this:
  - ./Styles/MudBlazor.scss (False)
  - ./Styles/MudBlazor.css (False)
  - ./Styles/MudBlazor.min.css (False)
  - ./Styles/MudBlazor.min.css (False)

From that we can learn the following:

My two guesses for the cause of this issue are:

What I don't quite get is why webcompiler is used in the test portion of the pipeline in the first place. Isn't that rather unnecessary?

mikes-gh commented 3 years ago

@stefanloerwald Sorry that link should have taken you directly to the log. I failed to account for the rerun which made the link invalid.

Part of the test cycle is to do a full build of all its referenced projects. It's what dotnet test does by default. This is a random failure so it cant be a configuration issue 80% of the test runs are fine. It is most likely a timing issue with the build server.

One thing I had to do was use the option "Preserve": false, because if the final destination min.css was changed outside of excubo then it was never overwritten. webcompiler only checked the intermediate file for changes by design I guess but in this case could lead to stale output.

mikes-gh commented 3 years ago

And we do component testing with bUnit so the js and css are needed for testing

stefanloerwald commented 3 years ago

It might actually be an issue around timing. I just remembered that I had to insert waits into my test code to make it work under linux, as the file timestamps have relatively low accuracy. Can you try inserting something like sleep 1 before changing the file?

mikes-gh commented 3 years ago

OK so this sounds like logic using timestamps. I think adjusting the test to make it pass may lead us to the issue. I am not sure what sleep 1 is. Is it a shell command? I am also not sure where to put it. Excuse my lack of understanding. In MSBuild it is not so easy to place a specific step in a specific place due to the target resolution order. This build runs on Windows mac (local) and ubuntu (ci).

stefanloerwald commented 3 years ago

Looking at your csproj files, it looks to me like the command is failing when it is executing for the second time. It would execute the first time for just the build, then a second time implicitly for the test. I don't see where waiting could actually help us. So let's scratch that. Why don't we try deleting the output files before every run of the command? With that, the tool should realize that a full run is necessary.

It could also be helpful to print the contents of the input/output folders before running the command. Maybe there's something to spot there.

mikes-gh commented 3 years ago

AFAIK The webcompiler command executes twice during testing. Once for each project in the solution that has the webcompiler referenced. MudBlazor.Docs and MudBlazor.

I don't see it executing for the test run as the solution is already built by then. I have a feeling this started after I added the Preserve: False parameter to the config. I solved one problem but created another. I will try to see if I can delete the files before build but the projects only build once from scratch (git clone) and those files are all in gitignore so are not present before the build anyway so I will be deleting files that arent there

 Determining projects to restore...
  All projects are up-to-date for restore.
  Generating Docs and Tests
  MudBlazor.Examples.Data -> /Users/mikes/Documents/Repos/MudBlazor/src/MudBlazor.Examples.Data/bin/Debug/net5.0/MudBlazor.Examples.Data.dll
  Docs.Compiler updated 0 generated files
  Docs.Compiler generated 0 new files
  Docs.Compiler completed in 553 msecs
  Tool 'excubo.webcompiler' (version '2.6.5') was restored. Available commands: webcompiler

  Restore was successful.
  MudBlazor -> /Users/mikes/Documents/Repos/MudBlazor/src/MudBlazor/bin/Debug/net5.0/MudBlazor.dll
  MudBlazor.Docs.Compiler -> /Users/mikes/Documents/Repos/MudBlazor/src/MudBlazor.Docs.Compiler/bin/Debug/net5.0/MudBlazor.Docs.Compiler.dll
  MudBlazor.UnitTests.Viewer -> /Users/mikes/Documents/Repos/MudBlazor/src/MudBlazor.UnitTests.Viewer/bin/Debug/net5.0/MudBlazor.UnitTests.Viewer.dll
  MudBlazor.UnitTests.Viewer (Blazor output) -> /Users/mikes/Documents/Repos/MudBlazor/src/MudBlazor.UnitTests.Viewer/bin/Debug/net5.0/wwwroot
  Tool 'excubo.webcompiler' (version '2.6.5') was restored. Available commands: webcompiler

  Restore was successful.
  MudBlazor.Docs -> /Users/mikes/Documents/Repos/MudBlazor/src/MudBlazor.Docs/bin/Debug/net5.0/MudBlazor.Docs.dll
  MudBlazor.UnitTests -> /Users/mikes/Documents/Repos/MudBlazor/src/MudBlazor.UnitTests/bin/Debug/net5.0/MudBlazor.UnitTests.dll
Test run for /Users/mikes/Documents/Repos/MudBlazor/src/MudBlazor.UnitTests/bin/Debug/net5.0/MudBlazor.UnitTests.dll (.NETCoreApp,Version=v5.0)
Microsoft (R) Test Execution Command Line Tool Version 16.8.3
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.

dotnet test should only build once.

mikes-gh commented 3 years ago

Another failure on the js side for comparism

A compilation step encountered an exception Could not find file '/home/vsts/work/1/s/src/MudBlazor/TScripts/combined/MudBlazor.min.js'. with stacktrace:
     at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
     at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
     at System.IO.FileStream.OpenHandle(FileMode mode, FileShare share, FileOptions options)
     at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
     at System.IO.File.ReadAllBytes(String path)
     at WebCompiler.Compile.Place.Compile(List`1 file_sequence) in /home/runner/work/WebCompiler/WebCompiler/WebCompiler/Compile/Place.cs:line 49
     at WebCompiler.Compile.CompilationStep.With(Compiler compiler) in /home/runner/work/WebCompiler/WebCompiler/WebCompiler/Compile/CompilationStep.cs:line 22

  The internal compiler Place encountered an exception: Could not find file '/home/vsts/work/1/s/src/MudBlazor/TScripts/combined/MudBlazor.min.js'.. 
  The stacktrace was:
     at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
     at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
     at System.IO.FileStream.OpenHandle(FileMode mode, FileShare share, FileOptions options)
     at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
     at System.IO.File.ReadAllBytes(String path)
     at WebCompiler.Compile.Place.Compile(List`1 file_sequence) in /home/runner/work/WebCompiler/WebCompiler/WebCompiler/Compile/Place.cs:line 49
     at WebCompiler.Compile.CompilationStep.With(Compiler compiler) in /home/runner/work/WebCompiler/WebCompiler/WebCompiler/Compile/CompilationStep.cs:line 22
  The state before this operations looked like this:
  - ./TScripts/combined/MudBlazor.js (False)
  - ./TScripts/combined/MudBlazor.min.js (False)
  - ./TScripts/combined/MudBlazor.min.js (False)
mikes-gh commented 3 years ago

I added some debug MSBuild Message tasks and can confirm the target that contains the webcompiler is only run once. However it is only the library target that fails and that has 2 webcompiler commands exec one after the other

<Target Name="WebCompiler" DependsOnTargets="ToolRestore;CombineJS">
    <Message Text="Running webcompiler" Importance="high"/>
    <!--compile and minify scss-->
    <Exec Command="dotnet webcompiler ./Styles/MudBlazor.scss -c excubowebcompiler.json" StandardOutputImportance="high" StandardErrorImportance="high" />
    <!--minify js-->
    <Exec Command="dotnet webcompiler ./TScripts/combined/MudBlazor.js -c excubowebcompiler.json" StandardOutputImportance="high" StandardErrorImportance="high" />
  </Target>
stefanloerwald commented 3 years ago

Maybe you can print some file lists and file timestamps? That could lead us to the issue.

mikes-gh commented 3 years ago

Ive just done a search on my emails to see when the builds started failing. I changed the config file to Preserve: false on the 3rd of Feb I don't have any failures before then. Its also the day we moved out library to net5

mikes-gh commented 3 years ago

The first failure was on the 5th of Feb

mikes-gh commented 3 years ago

I am running the build with preserve :true to see if it has any effect on the failures.

mikes-gh commented 3 years ago

Since running Preserve:true I have not had any failures. Looks like there is an issue with running Preserve:false (on Linux at least). Maybe something to do with file system differences. The reason I was using Preserve:false was to force a check on the final output file. With Preserve:true webcompiler only compared the intermediate file for changes and didn't copy over the final output file if the intermediate file showed no changes. Therefore you could end up with a stale output file.

mikes-gh commented 3 years ago

Still all OK on Preserve:true Maybe because people aren't using this parameter this bug hasn't surfaced yet. For now I am happy this works but this should be fixed really.

stefanloerwald commented 3 years ago

Thanks for investigating further. So to summarise: It seems to be a combination of --output-dir some/path and --preserve disable that results in issues on linux. I'll try to replicate that.

mikes-gh commented 3 years ago

Yes thats correct. Also when preserve : true the final destination file is never checked to see if its different from the intermediate file.

stefanloerwald commented 3 years ago

I have added some more tests (see https://github.com/excubo-ag/WebCompiler/blob/main/Tests_WebCompiler/NoPreserveTests.cs) which should replicate the settings, but also pass on linux. Can you perhaps log some more information, such as the files that exist on hard disk before & after the run of webcompiler in both the input and output directory?

mikes-gh commented 3 years ago

Shouldn't we try and get the tests passing without adding delays? Because your code should maybe cope with a certain timestamp diff tolerance. I did that on one of my apps

                else if (Math.Abs((roccFile.FileInfo.LastWriteTimeUtc - trackedFile?.ModifiedDate).Value.Milliseconds) > 1)
stefanloerwald commented 3 years ago

I don't see how the filestamp test could be incorrect: if (File.Exists(output_file) && new FileInfo(file).LastWriteTimeUtc < new FileInfo(output_file).LastWriteTimeUtc). Only if this condition is true is a step skipped.

In your case the input files don't change, right?

MichaelHochriegl commented 2 years ago

Any further info on this? I'm facing the same problem on my Fedora machine right now and regardless of preserve I get the error code 134 alongside the message The futex facility returned an unexpected error code. and a notification that dotnet crashed.

stefanloerwald commented 2 years ago

Hi @MichaelHochriegl,

There hasn't been any more investigation from my side as I don't have any machine/environment that exhibits this issue. So if this is on the critical path for you, the only thing I can help with is reviewing a pull request.

Best regards Stefan