From 3092d861540bcbc3c4fe341f160a5a22bc02c102 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Tue, 16 Jul 2024 17:31:10 +0200 Subject: [PATCH 1/6] Increasing the tolerance for Mono Runtime for the flaky ProcessThreadTests.TestStartTimeProperty test, fixes #103448 --- .../System.Diagnostics.Process/tests/ProcessThreadTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs index 6db4fd1a2cdee..9c0caecd32737 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs @@ -111,7 +111,9 @@ public void TestStartTimeProperty_OSX() [PlatformSpecific(TestPlatforms.Linux|TestPlatforms.Windows)] // OSX and FreeBSD throw PNSE from StartTime public async Task TestStartTimeProperty() { - TimeSpan allowedWindow = TimeSpan.FromSeconds(2); + TimeSpan allowedWindow = PlatformDetection.IsMonoRuntime + ? TimeSpan.FromSeconds(15) + : TimeSpan.FromSeconds(2); using (Process p = Process.GetCurrentProcess()) { From 6d17edc078e8ffe08f67c3e46d182b8cc632e9e6 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Wed, 17 Jul 2024 13:56:04 +0200 Subject: [PATCH 2/6] select the thread based on current thread native id, remove the try catch block: - it can hide LINQ issues as LINQ may throw InvalidOperationException - it's not needed for the current thread, because the code is still running so we know the thread is alive --- .../tests/ProcessThreadTests.cs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs index 9c0caecd32737..279f114a8576b 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs @@ -7,6 +7,7 @@ using Microsoft.DotNet.RemoteExecutor; using Xunit; using System.Threading.Tasks; +using System.Runtime.InteropServices; namespace System.Diagnostics.Tests { @@ -108,7 +109,7 @@ public void TestStartTimeProperty_OSX() } [Fact] - [PlatformSpecific(TestPlatforms.Linux|TestPlatforms.Windows)] // OSX and FreeBSD throw PNSE from StartTime + [PlatformSpecific(TestPlatforms.Linux | TestPlatforms.Windows)] // OSX and FreeBSD throw PNSE from StartTime public async Task TestStartTimeProperty() { TimeSpan allowedWindow = PlatformDetection.IsMonoRuntime @@ -150,17 +151,22 @@ public async Task TestStartTimeProperty() await Task.Factory.StartNew(() => { p.Refresh(); - try - { - var newest = p.Threads.Cast().OrderBy(t => t.StartTime.ToUniversalTime()).Last(); - Assert.InRange(newest.StartTime.ToUniversalTime(), curTime - allowedWindow, DateTime.Now.ToUniversalTime() + allowedWindow); - } - catch (InvalidOperationException) - { - // A thread may have gone away between our getting its info and attempting to access its StartTime - } + + int newThreadId = OperatingSystem.IsWindows() ? GetCurrentThreadId() : gettid(); + + ProcessThread[] processThreads = p.Threads.Cast().ToArray(); + ProcessThread newThread = Assert.Single(processThreads, thread => thread.Id == newThreadId); + + Assert.InRange(newThread.StartTime.ToUniversalTime(), curTime - allowedWindow, DateTime.Now.ToUniversalTime() + allowedWindow); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); } + + [DllImport("libc")] + static extern int gettid(); + + [DllImport("kernel32.dll")] + [SuppressGCTransition] + static extern int GetCurrentThreadId(); } [Fact] From 2cc7ecbf401ba36deff012a7705ecd0a3ecd6615 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Wed, 17 Jul 2024 14:43:06 +0200 Subject: [PATCH 3/6] Revert "Increasing the tolerance for Mono Runtime for the flaky ProcessThreadTests.TestStartTimeProperty test, fixes #103448" This reverts commit 3092d861540bcbc3c4fe341f160a5a22bc02c102. --- .../System.Diagnostics.Process/tests/ProcessThreadTests.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs index 279f114a8576b..2dd07e541434e 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs @@ -112,9 +112,7 @@ public void TestStartTimeProperty_OSX() [PlatformSpecific(TestPlatforms.Linux | TestPlatforms.Windows)] // OSX and FreeBSD throw PNSE from StartTime public async Task TestStartTimeProperty() { - TimeSpan allowedWindow = PlatformDetection.IsMonoRuntime - ? TimeSpan.FromSeconds(15) - : TimeSpan.FromSeconds(2); + TimeSpan allowedWindow = TimeSpan.FromSeconds(2); using (Process p = Process.GetCurrentProcess()) { From d9350ff3f4af0edefee81b53ed800dd241bfbb08 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Wed, 17 Jul 2024 17:46:09 +0200 Subject: [PATCH 4/6] fix the Linux build: gettid is not exposed in older versions of libc --- .../tests/ProcessThreadTests.Unix.cs | 6 ++++++ .../tests/ProcessThreadTests.cs | 9 +-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs index 2a0f26c1a7a3d..3c74fb35e9c1d 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; +using System.Runtime.InteropServices; using System.Threading; using Microsoft.DotNet.RemoteExecutor; using Xunit; @@ -30,5 +31,10 @@ public void TestPriorityLevelProperty_Unix() Assert.Throws(() => thread.PriorityLevel = level); } + + private static int GetCurrentThreadId() => syscall(186); // SYS_gettid + + [DllImport("libc")] + private static extern int syscall(int nr); } } diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs index 2dd07e541434e..843474a5f6cc2 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs @@ -150,7 +150,7 @@ await Task.Factory.StartNew(() => { p.Refresh(); - int newThreadId = OperatingSystem.IsWindows() ? GetCurrentThreadId() : gettid(); + int newThreadId = GetCurrentThreadId(); ProcessThread[] processThreads = p.Threads.Cast().ToArray(); ProcessThread newThread = Assert.Single(processThreads, thread => thread.Id == newThreadId); @@ -158,13 +158,6 @@ await Task.Factory.StartNew(() => Assert.InRange(newThread.StartTime.ToUniversalTime(), curTime - allowedWindow, DateTime.Now.ToUniversalTime() + allowedWindow); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); } - - [DllImport("libc")] - static extern int gettid(); - - [DllImport("kernel32.dll")] - [SuppressGCTransition] - static extern int GetCurrentThreadId(); } [Fact] From 0de69479fd475776b69c3f30efe920e1861d46f5 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Thu, 18 Jul 2024 16:06:52 +0200 Subject: [PATCH 5/6] Make the test conditional --- .../System.Diagnostics.Process/tests/ProcessThreadTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs index 843474a5f6cc2..31e07542aac42 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs @@ -108,7 +108,7 @@ public void TestStartTimeProperty_OSX() } } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [PlatformSpecific(TestPlatforms.Linux | TestPlatforms.Windows)] // OSX and FreeBSD throw PNSE from StartTime public async Task TestStartTimeProperty() { From dabec4ff0a36d435d5402de182596ebf825e6d2b Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Fri, 19 Jul 2024 11:53:06 +0200 Subject: [PATCH 6/6] get SYS_gettid value specific to given architecture (and hopefully fix the build for arm64) --- .../tests/ProcessThreadTests.Unix.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs index 3c74fb35e9c1d..d7ce1abcdb556 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs @@ -32,7 +32,23 @@ public void TestPriorityLevelProperty_Unix() Assert.Throws(() => thread.PriorityLevel = level); } - private static int GetCurrentThreadId() => syscall(186); // SYS_gettid + private static int GetCurrentThreadId() + { + // The magic values come from https://github.com/torvalds/linux. + int SYS_gettid = RuntimeInformation.ProcessArchitecture switch + { + Architecture.Arm => 224, + Architecture.Arm64 => 178, + Architecture.X86 => 224, + Architecture.X64 => 186, + Architecture.S390x => 236, + Architecture.Ppc64le => 207, + Architecture.RiscV64 => 178, + _ => 178, + }; + + return syscall(SYS_gettid); + } [DllImport("libc")] private static extern int syscall(int nr);