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

[dotnet-runtime-perf][wasm] Perf_File.CopyToOverwrite benchmark failing with System.IO.IOException: File exists #74104

Closed
radical opened this issue Aug 17, 2022 · 10 comments · Fixed by dotnet/performance#2601
Assignees
Labels
arch-wasm WebAssembly architecture area-System.IO blocking-clean-ci-optional Blocking optional rolling runs in-pr There is an active PR which will close this issue when it is merged
Milestone

Comments

@radical
Copy link
Member

radical commented Aug 17, 2022

With wasm/aot (build 20220817.1):

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.IO.IOException: File exists
   at BenchmarkDotNet.Autogenerated.Runnable_48.Run(IHost host, String benchmarkName)
   at System.Reflection.MethodInvoker.InterpretedInvoke(Object , Span`1 , BindingFlags )
   --- End of inner exception stack trace ---
   at BenchmarkDotNet.Autogenerated.UniqueProgramName.AfterAssemblyLoadingAttached(String[] args)

Full run:

// Found 1 benchmarks:
//   Perf_File.CopyToOverwrite: Job-AFOGNL(PowerPlanMode=00000000-0000-0000-0000-000000000000, Runtime=Wasm, Toolchain=Wasm, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1) [size=104857600]

// **************************
// Benchmark: Perf_File.CopyToOverwrite: Job-AFOGNL(PowerPlanMode=00000000-0000-0000-0000-000000000000, Runtime=Wasm, Toolchain=Wasm, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1) [size=104857600]
// *** Execute ***
// Launch: 1 / 1
// Execute: /home/helixbot/.jsvu/v8 --expose_wasm test-main.js -- --run 372a2e50-2c5c-4b96-b4d4-9fdc4d0208d3.dll --benchmarkName "System.IO.Tests.Perf_File.CopyToOverwrite(size: 104857600)" --job "PowerPlanMode=00000000-0000-0000-0000-000000000000, Runtime=Wasm, Toolchain=Wasm, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1" --benchmarkId 48  in /home/helixbot/work/AD350993/w/A75B092C/e/performance/artifacts/bin/for-running/MicroBenchmarks/372a2e50-2c5c-4b96-b4d4-9fdc4d0208d3/bin/net7.0/browser-wasm/AppBundle
Failed to set up high priority. Make sure you have the right permissions. Message: Permission denied
Incoming arguments: --run 372a2e50-2c5c-4b96-b4d4-9fdc4d0208d3.dll --benchmarkName System.IO.Tests.Perf_File.CopyToOverwrite(size: 104857600) --job PowerPlanMode=00000000-0000-0000-0000-000000000000, Runtime=Wasm, Toolchain=Wasm, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1 --benchmarkId 48
Application arguments: --run 372a2e50-2c5c-4b96-b4d4-9fdc4d0208d3.dll --benchmarkName System.IO.Tests.Perf_File.CopyToOverwrite(size: 104857600) --job PowerPlanMode=00000000-0000-0000-0000-000000000000, Runtime=Wasm, Toolchain=Wasm, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1 --benchmarkId 48
console.debug: mono_wasm_runtime_ready fe00e07a-5519-4dfe-b35a-f867dbaf2e28
console.info: Initializing.....
// BeforeAnythingElse

// Benchmark Process Environment Information:
// Runtime=.NET Core (Mono) 7.0.0-ci, Wasm NativeAOT
// GC=Non-concurrent Workstation
// Job: Job-SSXSXT(PowerPlanMode=00000000-0000-0000-0000-000000000000, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1)


System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.IO.IOException: File exists
   at BenchmarkDotNet.Autogenerated.Runnable_48.Run(IHost host, String benchmarkName)
   at System.Reflection.MethodInvoker.InterpretedInvoke(Object , Span`1 , BindingFlags )
   --- End of inner exception stack trace ---
   at BenchmarkDotNet.Autogenerated.UniqueProgramName.AfterAssemblyLoadingAttached(String[] args)
// AfterAll
{"name":"ExitStatus","message":"Program terminated with exit(-1)","status":-1}
No Workload Results were obtained from the run.
// Benchmark Process 7089 has exited with code 255.

cc @adamsitnik @LoopedBard3

@adamsitnik
Copy link
Member

@radical This particular benchmark should overwrite any existing files:

https://github.com/dotnet/performance/blob/3edf4c3149f5c903777f13af9b08b562b1672302/src/benchmarks/micro/libraries/System.IO.FileSystem/Perf.File.cs#L272

So it looks like a product bug?

@radical
Copy link
Member Author

radical commented Aug 17, 2022

How do I run a single benchmark locally? I know how to run the whole thing or partitions.

@adamsitnik
Copy link
Member

How do I run a single benchmark locally? I know how to run the whole thing or partitions.

You need to specify filter, which is a glob pattern applied to namespace.typeName.methodName. In your case the simplest one will be:

--filter '*CopyToOverwrite'

(remember to escape asterisk on Unixes)

@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@radical radical transferred this issue from dotnet/performance Aug 17, 2022
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Aug 17, 2022
@radical radical added blocking-clean-ci-optional Blocking optional rolling runs area-System.IO and removed pipeline blocker labels Aug 17, 2022
@ghost
Copy link

ghost commented Aug 17, 2022

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

Issue Details

With wasm/aot (build 20220817.1):

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.IO.IOException: File exists
   at BenchmarkDotNet.Autogenerated.Runnable_48.Run(IHost host, String benchmarkName)
   at System.Reflection.MethodInvoker.InterpretedInvoke(Object , Span`1 , BindingFlags )
   --- End of inner exception stack trace ---
   at BenchmarkDotNet.Autogenerated.UniqueProgramName.AfterAssemblyLoadingAttached(String[] args)

Full run:

// Found 1 benchmarks:
//   Perf_File.CopyToOverwrite: Job-AFOGNL(PowerPlanMode=00000000-0000-0000-0000-000000000000, Runtime=Wasm, Toolchain=Wasm, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1) [size=104857600]

// **************************
// Benchmark: Perf_File.CopyToOverwrite: Job-AFOGNL(PowerPlanMode=00000000-0000-0000-0000-000000000000, Runtime=Wasm, Toolchain=Wasm, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1) [size=104857600]
// *** Execute ***
// Launch: 1 / 1
// Execute: /home/helixbot/.jsvu/v8 --expose_wasm test-main.js -- --run 372a2e50-2c5c-4b96-b4d4-9fdc4d0208d3.dll --benchmarkName "System.IO.Tests.Perf_File.CopyToOverwrite(size: 104857600)" --job "PowerPlanMode=00000000-0000-0000-0000-000000000000, Runtime=Wasm, Toolchain=Wasm, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1" --benchmarkId 48  in /home/helixbot/work/AD350993/w/A75B092C/e/performance/artifacts/bin/for-running/MicroBenchmarks/372a2e50-2c5c-4b96-b4d4-9fdc4d0208d3/bin/net7.0/browser-wasm/AppBundle
Failed to set up high priority. Make sure you have the right permissions. Message: Permission denied
Incoming arguments: --run 372a2e50-2c5c-4b96-b4d4-9fdc4d0208d3.dll --benchmarkName System.IO.Tests.Perf_File.CopyToOverwrite(size: 104857600) --job PowerPlanMode=00000000-0000-0000-0000-000000000000, Runtime=Wasm, Toolchain=Wasm, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1 --benchmarkId 48
Application arguments: --run 372a2e50-2c5c-4b96-b4d4-9fdc4d0208d3.dll --benchmarkName System.IO.Tests.Perf_File.CopyToOverwrite(size: 104857600) --job PowerPlanMode=00000000-0000-0000-0000-000000000000, Runtime=Wasm, Toolchain=Wasm, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1 --benchmarkId 48
console.debug: mono_wasm_runtime_ready fe00e07a-5519-4dfe-b35a-f867dbaf2e28
console.info: Initializing.....
// BeforeAnythingElse

// Benchmark Process Environment Information:
// Runtime=.NET Core (Mono) 7.0.0-ci, Wasm NativeAOT
// GC=Non-concurrent Workstation
// Job: Job-SSXSXT(PowerPlanMode=00000000-0000-0000-0000-000000000000, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, WarmupCount=1)


System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.IO.IOException: File exists
   at BenchmarkDotNet.Autogenerated.Runnable_48.Run(IHost host, String benchmarkName)
   at System.Reflection.MethodInvoker.InterpretedInvoke(Object , Span`1 , BindingFlags )
   --- End of inner exception stack trace ---
   at BenchmarkDotNet.Autogenerated.UniqueProgramName.AfterAssemblyLoadingAttached(String[] args)
// AfterAll
{"name":"ExitStatus","message":"Program terminated with exit(-1)","status":-1}
No Workload Results were obtained from the run.
// Benchmark Process 7089 has exited with code 255.

cc @adamsitnik @LoopedBard3

Author: radical
Assignees: -
Labels:

area-System.IO, untriaged, blocking-clean-ci-optional

Milestone: -

@radical radical added the arch-wasm WebAssembly architecture label Aug 17, 2022
@jozkee
Copy link
Member

jozkee commented Aug 19, 2022

@adamsitnik could this be a regression in 7.0?

@adamsitnik
Copy link
Member

could this be a regression in 7.0?

@jozkee It could, but this benchmark runs on CLR on Unix pretty fine, so I am sure that it's wasm-specific issue.

@radical is someone from the WASM Team going to investigate it?

@adamsitnik adamsitnik added this to the 8.0.0 milestone Aug 19, 2022
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Aug 19, 2022
@radical radical self-assigned this Sep 6, 2022
@radical
Copy link
Member Author

radical commented Sep 7, 2022

  • I'm not able to reproduce this locally.
  • it happens for CopyTo, CopyToOverride, and ReadAllBytes, but not always
  • it happens only with wasm/AOT
  • I think the exception is thrown from the SetupReadAllBytes method:

https://github.com/dotnet/performance/blob/5f63e8dcf81a0f9ddf5a80bd791d1fbaf0babd61/src/benchmarks/micro/libraries/System.IO.FileSystem/Perf.File.cs#L92-L113

.. and all the failing benchmarks are using this setup method:

GlobalSetup(Targets = new[] { nameof(ReadAllBytes), "ReadAllBytesAsync", nameof(CopyTo), nameof(CopyToOverwrite) })]

The same issue on main shows the file name /tmp/:

---> System.IO.IOException: The file '/tmp/' already exists.
  at BenchmarkDotNet.Autogenerated.Runnable_48.Run(IHost host, String benchmarkName)
  at System.Reflection.MethodInvoker.InterpretedInvoke(Object , Span`1 , BindingFlags )
  --- End of inner exception stack trace ---
  at BenchmarkDotNet.Autogenerated.UniqueProgramName.AfterAssemblyLoadingAttached(String[] args)

I will debug the issue on CI.

@danmoseley
Copy link
Member

@radical Dupe of #73721 ?

@radical
Copy link
Member Author

radical commented Sep 7, 2022

@radical Dupe of #73721 ?

Possibly, though here it runs with v8 instead of nodejs.
The code here just needs a random name for the file, but Path.GetTempFileName will try to create the file, and is probably running into this issue. I'll open a PR to update that.
Thanks @danmoseley!

radical added a commit to radical/performance that referenced this issue Sep 7, 2022
On wasm/aot, `System.IO.FileSystem/Perf.File`'s `CopyTo`, `CopyToOverride`, and `ReadAllBytes` benchmarks fail randomly with:
```
---> System.IO.IOException: The file '/tmp/' already exists.
  at BenchmarkDotNet.Autogenerated.Runnable_48.Run(IHost host, String benchmarkName)
  at System.Reflection.MethodInvoker.InterpretedInvoke(Object , Span`1 , BindingFlags )
  --- End of inner exception stack trace ---
  at BenchmarkDotNet.Autogenerated.UniqueProgramName.AfterAssemblyLoadingAttached(String[] args)
```

.. due to `Path.GetTempFileName()` being buggy - dotnet/runtime#73721.

In `SetupReadAllBytes`, we are building the test file path as:
```csharp
_testFilePath = Path.Combine(baseDir, Path.GetTempFileName())
```

.. but the `Path.GetTempFileName()` is not appropriate here, as it will
return a full path, and it will create the file. Instead we can use
`Path.GetRandomFileName()` which should avoid the underlying issue
completely.

Fixes dotnet/runtime#74104 .
@radical radical added the in-pr There is an active PR which will close this issue when it is merged label Sep 7, 2022
adamsitnik pushed a commit to dotnet/performance that referenced this issue Sep 8, 2022
On wasm/aot, `System.IO.FileSystem/Perf.File`'s `CopyTo`, `CopyToOverride`, and `ReadAllBytes` benchmarks fail randomly with:
```
---> System.IO.IOException: The file '/tmp/' already exists.
  at BenchmarkDotNet.Autogenerated.Runnable_48.Run(IHost host, String benchmarkName)
  at System.Reflection.MethodInvoker.InterpretedInvoke(Object , Span`1 , BindingFlags )
  --- End of inner exception stack trace ---
  at BenchmarkDotNet.Autogenerated.UniqueProgramName.AfterAssemblyLoadingAttached(String[] args)
```

.. due to `Path.GetTempFileName()` being buggy - dotnet/runtime#73721.

In `SetupReadAllBytes`, we are building the test file path as:
```csharp
_testFilePath = Path.Combine(baseDir, Path.GetTempFileName())
```

.. but the `Path.GetTempFileName()` is not appropriate here, as it will
return a full path, and it will create the file. Instead we can use
`Path.GetRandomFileName()` which should avoid the underlying issue
completely.

Fixes dotnet/runtime#74104 .
@ghost ghost locked as resolved and limited conversation to collaborators Oct 8, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
arch-wasm WebAssembly architecture area-System.IO blocking-clean-ci-optional Blocking optional rolling runs in-pr There is an active PR which will close this issue when it is merged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants