Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit d73eb91

Browse files
authored
Fix thread constructor test on newer kernels (#28613)
Works around and closes https://github.com/dotnet/coreclr/issues/17170 - Works around an issue on linux-arm64 where pthread_create appears to reserve less stack space than requested without failing, and limits the max reserved stack size to the ulimit-configued value, leading to seg fault when the requested size of stack space is attempted to be used - Fixed to write every page in the stack region that is being checked, to guarantee hitting the guard page in case of failure. The JIT's stack probe for stackalloc should cover this, https://github.com/dotnet/coreclr/issues/16827 details why that was not happening, in any case this test is not intended to test stack probing behavior, so this change makes the test a bit stronger in what it actually intends to test.
1 parent a9a5ca9 commit d73eb91

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

src/System.Threading.Thread/tests/ThreadTests.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public static partial class ThreadTests
2626
[Fact]
2727
public static void ConstructorTest()
2828
{
29+
const int SmallStackSize = 64 << 10; // 64 KB, currently accepted in all supported platforms, and is the PAL minimum
30+
const int LargeStackSize = 2 << 20; // 2 MB, see https://github.com/dotnet/coreclr/issues/17170
31+
32+
int pageSizeBytes = Environment.SystemPageSize;
33+
2934
Action<Thread> startThreadAndJoin =
3035
t =>
3136
{
@@ -38,22 +43,25 @@ public static void ConstructorTest()
3843
{
3944
// Try to stack-allocate an array to verify that close to the expected amount of stack space is actually
4045
// available
41-
int bufferSizeBytes = Math.Max(16 << 10, stackSizeBytes - (64 << 10));
46+
int bufferSizeBytes = Math.Max(16 << 10, stackSizeBytes - SmallStackSize);
4247
unsafe
4348
{
4449
byte* buffer = stackalloc byte[bufferSizeBytes];
45-
Volatile.Write(ref buffer[0], 0xff);
50+
for (int i = 0; i < bufferSizeBytes; i += pageSizeBytes)
51+
{
52+
Volatile.Write(ref buffer[i], 0xff);
53+
}
4654
Volatile.Write(ref buffer[bufferSizeBytes - 1], 0xff);
4755
}
4856
};
4957
startThreadAndJoin(new Thread(() => verifyStackSize(0)));
5058
startThreadAndJoin(new Thread(() => verifyStackSize(0), 0));
51-
startThreadAndJoin(new Thread(() => verifyStackSize(64 << 10), 64 << 10)); // 64 KB
52-
startThreadAndJoin(new Thread(() => verifyStackSize(16 << 20), 16 << 20)); // 16 MB
59+
startThreadAndJoin(new Thread(() => verifyStackSize(SmallStackSize), SmallStackSize));
60+
startThreadAndJoin(new Thread(() => verifyStackSize(LargeStackSize), LargeStackSize));
5361
startThreadAndJoin(new Thread(state => verifyStackSize(0)));
5462
startThreadAndJoin(new Thread(state => verifyStackSize(0), 0));
55-
startThreadAndJoin(new Thread(state => verifyStackSize(64 << 10), 64 << 10)); // 64 KB
56-
startThreadAndJoin(new Thread(state => verifyStackSize(16 << 20), 16 << 20)); // 16 MB
63+
startThreadAndJoin(new Thread(state => verifyStackSize(SmallStackSize), SmallStackSize));
64+
startThreadAndJoin(new Thread(state => verifyStackSize(LargeStackSize), LargeStackSize));
5765

5866
Assert.Throws<ArgumentNullException>(() => new Thread((ThreadStart)null));
5967
Assert.Throws<ArgumentNullException>(() => new Thread((ThreadStart)null, 0));

0 commit comments

Comments
 (0)