Description
Calling Process.HandleCount on a cached handle can cause an AccessViolationException on Linux (WSL)
Reproduction Steps
https://github.com/prometheus-net/prometheus-net/blob/60e9106a83ff1274fec0022c37366f04822b1d1b/Prometheus/DotNetStats.cs#L74-L97
public sealed class DotNetStats
{
private readonly Process _process;
private Gauge _openHandles;
private DotNetStats(IMetricFactory metricFactory)
{
_process = Process.GetCurrentProcess();
_openHandles = metricFactory.CreateGauge("process_open_handles", "Number of open handles");
}
private readonly object _updateLock = new object();
public void UpdateMetrics()
{
try
{
lock (_updateLock)
{
_process.Refresh();
_openHandles.Set(_process.HandleCount);
}
}
catch (Exception)
{
}
}
}
Expected behavior
Calling UpdateMetrics sets the number of process handles
Actual behavior
Infrequent (about 6 hours of being called every 5 seconds)
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at System.SpanHelpers.NonPackedIndexOfValueType[[System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.SpanHelpers+DontNegate`1[[System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Byte ByRef, Byte, Int32)
at System.IO.Enumeration.FileSystemEntry.Initialize(System.IO.Enumeration.FileSystemEntry ByRef, DirectoryEntry, System.ReadOnlySpan`1<Char>, System.ReadOnlySpan`1<Char>, System.ReadOnlySpan`1<Char>, System.Span`1<Char>)
at System.IO.Enumeration.FileSystemEnumerator`1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
at System.Collections.Generic.List`1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]..ctor(System.Collections.Generic.IEnumerable`1<System.__Canon>)
at System.Diagnostics.Process.EnsureHandleCountPopulated()
at Prometheus.DotNetStats.UpdateMetrics()
Regression?
Not sure as first time have run on WSL; haven't had any issues on Windows or seen any complaints from Linux, macOS users
Known Workarounds
No workaround as AccessViolationException always bubbles through catches to crash process
Configuration
WSL on Windows 11 23H2 (OS Build 22631.4112)
.NET SDK:
Version: 8.0.108
Commit: 665a05cea7
Workload version: 8.0.100-manifests.109ff937
Runtime Environment:
OS Name: ubuntu
OS Version: 22.04
OS Platform: Linux
RID: ubuntu.22.04-x64
Base Path: /usr/lib/dotnet/sdk/8.0.108/
.NET workloads installed:
Workload version: 8.0.100-manifests.109ff937
There are no installed workloads to display.
Host:
Version: 8.0.8
Architecture: x64
Commit: 08338fcaa5
.NET SDKs installed:
8.0.108 [/usr/lib/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 8.0.8 [/usr/lib/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 8.0.8 [/usr/lib/dotnet/shared/Microsoft.NETCore.App]
Other information
Aside; creating all the strings for the filenames in /proc/{pid}/fd just to find the count of files doesn't seem very efficient
|
_processInfo.HandleCount = Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly).Length; |
Description
Calling
Process.HandleCounton a cached handle can cause anAccessViolationExceptionon Linux (WSL)Reproduction Steps
https://github.com/prometheus-net/prometheus-net/blob/60e9106a83ff1274fec0022c37366f04822b1d1b/Prometheus/DotNetStats.cs#L74-L97
Expected behavior
Calling
UpdateMetricssets the number of process handlesActual behavior
Infrequent (about 6 hours of being called every 5 seconds)
Regression?
Not sure as first time have run on WSL; haven't had any issues on Windows or seen any complaints from Linux, macOS users
Known Workarounds
No workaround as
AccessViolationExceptionalways bubbles through catches to crash processConfiguration
WSL on Windows 11 23H2 (OS Build 22631.4112)
Other information
Aside; creating all the strings for the filenames in
/proc/{pid}/fdjust to find the count of files doesn't seem very efficientruntime/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Linux.cs
Line 172 in c4792a2