From cc7baab5d14c2523b6f71221460a45318b8aca9b Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Wed, 6 May 2020 20:25:44 +0200 Subject: [PATCH 1/2] Fix the stackoverflow test output checks The System.Threading.ThreadHelper.ThreadStart can tail call the System.Threading.ExecutionContext.RunInternal (and some other methods in the runtime as well) and thus it would not be visible on the stack trace. So the fix is to not to look at the System.Threading.ThreadHelper.ThreadStart in the stack trace and use a method in the test itself instead. Since the test is compiled with optimizations disabled, JIT should not do any "interesting" things. --- .../exceptions/stackoverflow/stackoverflow.cs | 23 +++++++++++-------- .../stackoverflow/stackoverflowtester.cs | 8 +++---- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs index 2cb9aa6ae82f49..bf84d49569363d 100644 --- a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs +++ b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs @@ -111,21 +111,24 @@ static void MainThreadTest(bool smallframe) } } + static void SecondaryThreadStart(bool smallframe) + { + if (smallframe) + { + InfiniteRecursionA(); + } + else + { + InfiniteRecursionA2(); + } + } + static void SecondaryThreadsTest(bool smallframe) { Thread[] threads = new Thread[32]; for (int i = 0; i < threads.Length; i++) { - threads[i] = new Thread(() => { - if (smallframe) - { - InfiniteRecursionA(); - } - else - { - InfiniteRecursionA2(); - } - }); + threads[i] = new Thread(() => SecondaryThreadStart(smallframe)); threads[i].Start(); } diff --git a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs index f30305658c1007..97a6d1e317b51a 100644 --- a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs +++ b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs @@ -147,9 +147,9 @@ static bool TestStackOverflowSmallFrameSecondaryThread() List lines; if (TestStackOverflow("stackoverflow", "smallframe secondary", out lines)) { - if (!lines[lines.Count - 1].EndsWith("at System.Threading.ThreadHelper.ThreadStart()")) + if (!lines.Exists(elem => elem.EndsWith("at TestStackOverflow.Program.SecondaryThreadStart(Boolean)"))) { - Console.WriteLine("Missing \"System.Threading.ThreadHelper.ThreadStart\" method frame at the last line"); + Console.WriteLine("Missing \"TestStackOverflow.Program.SecondaryThreadStart\" method frame"); return false; } @@ -182,9 +182,9 @@ static bool TestStackOverflowLargeFrameSecondaryThread() List lines; if (TestStackOverflow("stackoverflow", "largeframe secondary", out lines)) { - if (!lines[lines.Count - 1].EndsWith("at System.Threading.ThreadHelper.ThreadStart()")) + if (!lines.Exists(elem => elem.EndsWith("at TestStackOverflow.Program.SecondaryThreadStart(Boolean)"))) { - Console.WriteLine("Missing \"System.Threading.ThreadHelper.ThreadStart\" method frame at the last line"); + Console.WriteLine("Missing \"TestStackOverflow.Program.SecondaryThreadStart\" method frame"); return false; } From 8f339616acfe73ca378608df5e034837d40128df Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Wed, 6 May 2020 22:07:55 +0200 Subject: [PATCH 2/2] Add NoInlining attribute and do a little unification --- .../exceptions/stackoverflow/stackoverflow.cs | 27 +++++++++---------- .../stackoverflow/stackoverflowtester.cs | 18 ++++++++----- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs index bf84d49569363d..3a4a363c7425bb 100644 --- a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs +++ b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; using System.Threading; +using System.Runtime.CompilerServices; namespace TestStackOverflow { @@ -67,51 +68,47 @@ struct LargeStruct65536 } class Program { + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionA() { InfiniteRecursionB(); } + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionB() { InfiniteRecursionC(); } + + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionC() { InfiniteRecursionA(); } + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionA2() { LargeStruct65536 s; InfiniteRecursionB2(); } + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionB2() { LargeStruct65536 s; InfiniteRecursionC2(); } + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionC2() { LargeStruct65536 s; InfiniteRecursionA2(); } - static void MainThreadTest(bool smallframe) - { - if (smallframe) - { - InfiniteRecursionA(); - } - else - { - InfiniteRecursionA2(); - } - } - - static void SecondaryThreadStart(bool smallframe) + [MethodImpl(MethodImplOptions.NoInlining)] + static void Test(bool smallframe) { if (smallframe) { @@ -128,7 +125,7 @@ static void SecondaryThreadsTest(bool smallframe) Thread[] threads = new Thread[32]; for (int i = 0; i < threads.Length; i++) { - threads[i] = new Thread(() => SecondaryThreadStart(smallframe)); + threads[i] = new Thread(() => Test(smallframe)); threads[i].Start(); } @@ -147,7 +144,7 @@ static void Main(string[] args) } else if (args[1] == "main") { - MainThreadTest(smallframe); + Test(smallframe); } } } diff --git a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs index 97a6d1e317b51a..d8326ff6666bf2 100644 --- a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs +++ b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs @@ -77,6 +77,12 @@ static bool TestStackOverflowSmallFrameMainThread() return false; } + if (!lines.Exists(elem => elem.EndsWith("TestStackOverflow.Program.Test(Boolean)"))) + { + Console.WriteLine("Missing \"Test\" method frame"); + return false; + } + if (!lines.Exists(elem => elem.EndsWith("at TestStackOverflow.Program.InfiniteRecursionA()"))) { Console.WriteLine("Missing \"InfiniteRecursionA\" method frame"); @@ -112,9 +118,9 @@ static bool TestStackOverflowLargeFrameMainThread() return false; } - if (!lines.Exists(elem => elem.EndsWith("TestStackOverflow.Program.MainThreadTest(Boolean)"))) + if (!lines.Exists(elem => elem.EndsWith("TestStackOverflow.Program.Test(Boolean)"))) { - Console.WriteLine("Missing \"MainThreadTest\" method frame"); + Console.WriteLine("Missing \"Test\" method frame"); return false; } @@ -147,9 +153,9 @@ static bool TestStackOverflowSmallFrameSecondaryThread() List lines; if (TestStackOverflow("stackoverflow", "smallframe secondary", out lines)) { - if (!lines.Exists(elem => elem.EndsWith("at TestStackOverflow.Program.SecondaryThreadStart(Boolean)"))) + if (!lines.Exists(elem => elem.EndsWith("at TestStackOverflow.Program.Test(Boolean)"))) { - Console.WriteLine("Missing \"TestStackOverflow.Program.SecondaryThreadStart\" method frame"); + Console.WriteLine("Missing \"TestStackOverflow.Program.Test\" method frame"); return false; } @@ -182,9 +188,9 @@ static bool TestStackOverflowLargeFrameSecondaryThread() List lines; if (TestStackOverflow("stackoverflow", "largeframe secondary", out lines)) { - if (!lines.Exists(elem => elem.EndsWith("at TestStackOverflow.Program.SecondaryThreadStart(Boolean)"))) + if (!lines.Exists(elem => elem.EndsWith("at TestStackOverflow.Program.Test(Boolean)"))) { - Console.WriteLine("Missing \"TestStackOverflow.Program.SecondaryThreadStart\" method frame"); + Console.WriteLine("Missing \"TestStackOverflow.Program.Test\" method frame"); return false; }