Skip to content

Commit 0686ce6

Browse files
Run System.Diagnostics.StackTrace tests with NAOT (#103151)
Also fixes some corner case issues, like whether an empty stacktrace should stringify into a newline.
1 parent 7cd8459 commit 0686ce6

File tree

8 files changed

+39
-26
lines changed

8 files changed

+39
-26
lines changed

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/StackTrace.NativeAot.cs

+8-7
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,19 @@ private void InitializeForIpAddressArray(IntPtr[] ipAddresses, int skipFrames, i
8080
#if !TARGET_WASM
8181
internal void ToString(TraceFormat traceFormat, StringBuilder builder)
8282
{
83-
if (_stackFrames == null)
83+
if (_stackFrames != null)
8484
{
85-
return;
86-
}
87-
88-
foreach (StackFrame frame in _stackFrames)
89-
{
90-
frame.AppendToStackTrace(builder);
85+
foreach (StackFrame frame in _stackFrames)
86+
{
87+
frame?.AppendToStackTrace(builder);
88+
}
9189
}
9290

9391
if (traceFormat == TraceFormat.Normal && builder.Length >= Environment.NewLine.Length)
9492
builder.Length -= Environment.NewLine.Length;
93+
94+
if (traceFormat == TraceFormat.TrailingNewLine && builder.Length == 0)
95+
builder.AppendLine();
9596
}
9697
#endif
9798
}

src/coreclr/nativeaot/System.Private.StackTraceMetadata/src/Internal/StackTraceMetadata/MethodNameFormatter.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,10 @@ private void EmitPointerTypeName(PointerSignatureHandle pointerSigHandle)
403403
/// <summary>
404404
/// Emit function pointer type.
405405
/// </summary>
406-
private void EmitFunctionPointerTypeName()
406+
private static void EmitFunctionPointerTypeName()
407407
{
408-
_outputBuilder.Append("IntPtr");
408+
// Function pointer types have no textual representation and we have tests making sure
409+
// they show up as empty strings in stack traces, so deliberately do nothing.
409410
}
410411

411412
/// <summary>

src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs

+1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ private static bool GetLinqExpressionsBuiltWithIsInterpretingOnly()
172172
public static bool IsAsyncFileIOSupported => !IsBrowser && !IsWasi;
173173

174174
public static bool IsLineNumbersSupported => !IsNativeAot;
175+
public static bool IsILOffsetsSupported => !IsNativeAot;
175176

176177
public static bool IsInContainer => GetIsInContainer();
177178
public static bool IsNotInContainer => !IsInContainer;

src/libraries/System.Diagnostics.StackTrace/tests/StackFrameExtensionsTests.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,21 @@ public static IEnumerable<object[]> StackFrame_TestData()
1616
yield return new object[] { new StackFrame(int.MaxValue) };
1717
}
1818

19-
[Theory]
19+
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNativeAot))]
2020
[MemberData(nameof(StackFrame_TestData))]
2121
public void HasNativeImage_StackFrame_ReturnsFalse(StackFrame stackFrame)
2222
{
2323
Assert.False(stackFrame.HasNativeImage());
2424
}
2525

26-
[Theory]
26+
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNativeAot))]
2727
[MemberData(nameof(StackFrame_TestData))]
2828
public void GetNativeIP_StackFrame_ReturnsZero(StackFrame stackFrame)
2929
{
3030
Assert.Equal(IntPtr.Zero, stackFrame.GetNativeIP());
3131
}
3232

33-
[Theory]
33+
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNativeAot))]
3434
[MemberData(nameof(StackFrame_TestData))]
3535
public void GetNativeImageBase_StackFrame_ReturnsZero(StackFrame stackFrame)
3636
{
@@ -43,7 +43,7 @@ public static IEnumerable<object[]> HasMethod_TestData()
4343
yield return new object[] { new StackFrame(int.MaxValue), false };
4444
}
4545

46-
[Theory]
46+
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsILOffsetsSupported))]
4747
[ActiveIssue("https://github.com/dotnet/runtime/issues/50957", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))]
4848
[MemberData(nameof(HasMethod_TestData))]
4949
public void HasILOffset_Invoke_ReturnsExpected(StackFrame stackFrame, bool expected)
@@ -59,6 +59,7 @@ public void HasILOffset_NullStackFrame_ThrowsNullReferenceException()
5959

6060
[Theory]
6161
[ActiveIssue("https://github.com/dotnet/runtime/issues/50957", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))]
62+
[ActiveIssue("https://github.com/dotnet/runtime/issues/103218", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
6263
[MemberData(nameof(HasMethod_TestData))]
6364
public void HasMethod_Invoke_ReturnsExpected(StackFrame stackFrame, bool expected)
6465
{
@@ -79,6 +80,7 @@ public static IEnumerable<object[]> HasSource_TestData()
7980
}
8081

8182
[Theory]
83+
[ActiveIssue("https://github.com/dotnet/runtime/issues/103218", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
8284
[MemberData(nameof(HasSource_TestData))]
8385
public void HasSource_Invoke_ReturnsExpected(StackFrame stackFrame, bool expected)
8486
{

src/libraries/System.Diagnostics.StackTrace/tests/StackFrameTests.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public void SkipFrames_CallMethod_ReturnsExpected()
7575
[Theory]
7676
[InlineData(int.MinValue)]
7777
[InlineData(int.MaxValue)]
78+
[ActiveIssue("https://github.com/dotnet/runtime/issues/103218", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
7879
public void SkipFrames_ManyFrames_HasNoMethod(int skipFrames)
7980
{
8081
var stackFrame = new StackFrame(skipFrames);
@@ -123,6 +124,7 @@ public static IEnumerable<object[]> ToString_TestData()
123124

124125
[Theory]
125126
[ActiveIssue("https://github.com/mono/mono/issues/15186", TestRuntimes.Mono)]
127+
[ActiveIssue("https://github.com/dotnet/runtime/issues/103156", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
126128
[MemberData(nameof(ToString_TestData))]
127129
public void ToString_Invoke_ReturnsExpected(StackFrame stackFrame, string expectedToString)
128130
{
@@ -168,7 +170,10 @@ private static void VerifyStackFrameSkipFrames(StackFrame stackFrame, bool isFil
168170
}
169171
else
170172
{
171-
Assert.True(stackFrame.GetILOffset() >= 0, $"Expected GetILOffset() {stackFrame.GetILOffset()} for {stackFrame} to be greater or equal to zero.");
173+
if (PlatformDetection.IsILOffsetsSupported)
174+
{
175+
Assert.True(stackFrame.GetILOffset() >= 0, $"Expected GetILOffset() {stackFrame.GetILOffset()} for {stackFrame} to be greater or equal to zero.");
176+
}
172177
}
173178

174179
// GetMethod returns null for unknown frames.

src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace System.Diagnostics.SymbolStore.Tests
99
{
1010
public class StackTraceSymbolsTests
1111
{
12-
[Fact]
12+
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.HasAssemblyFiles))]
1313
[ActiveIssue("https://github.com/dotnet/runtime/issues/51399", TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst)]
1414
public void StackTraceSymbolsDoNotLockFile()
1515
{

src/libraries/System.Diagnostics.StackTrace/tests/StackTraceTests.cs

+14-10
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void MethodsToSkip_Get_ReturnsZero()
4747
public void Ctor_Default()
4848
{
4949
var stackTrace = new StackTrace();
50-
VerifyFrames(stackTrace, false);
50+
VerifyFrames(stackTrace, false, 0);
5151
}
5252

5353
[Theory]
@@ -57,7 +57,7 @@ public void Ctor_Default()
5757
public void Ctor_FNeedFileInfo(bool fNeedFileInfo)
5858
{
5959
var stackTrace = new StackTrace(fNeedFileInfo);
60-
VerifyFrames(stackTrace, fNeedFileInfo);
60+
VerifyFrames(stackTrace, fNeedFileInfo, 0);
6161
}
6262

6363
[Theory]
@@ -73,7 +73,7 @@ public void Ctor_SkipFrames(int skipFrames)
7373
Assert.Equal(emptyStackTrace.FrameCount - skipFrames, stackTrace.FrameCount);
7474
Assert.Equal(expectedMethods, stackTrace.GetFrames().Select(f => f.GetMethod()));
7575

76-
VerifyFrames(stackTrace, false);
76+
VerifyFrames(stackTrace, false, skipFrames);
7777
}
7878

7979
[Fact]
@@ -99,7 +99,7 @@ public void Ctor_SkipFrames_FNeedFileInfo(int skipFrames, bool fNeedFileInfo)
9999
Assert.Equal(emptyStackTrace.FrameCount - skipFrames, stackTrace.FrameCount);
100100
Assert.Equal(expectedMethods, stackTrace.GetFrames().Select(f => f.GetMethod()));
101101

102-
VerifyFrames(stackTrace, fNeedFileInfo);
102+
VerifyFrames(stackTrace, fNeedFileInfo, skipFrames);
103103
}
104104

105105
[Theory]
@@ -117,7 +117,7 @@ public void Ctor_LargeSkipFramesFNeedFileInfo_GetFramesReturnsEmpty(bool fNeedFi
117117
public void Ctor_ThrownException_GetFramesReturnsExpected()
118118
{
119119
var stackTrace = new StackTrace(InvokeException());
120-
VerifyFrames(stackTrace, false);
120+
VerifyFrames(stackTrace, false, 0);
121121
}
122122

123123
[Fact]
@@ -137,7 +137,7 @@ public void Ctor_EmptyException_GetFramesReturnsEmpty()
137137
public void Ctor_Bool_ThrownException_GetFramesReturnsExpected(bool fNeedFileInfo)
138138
{
139139
var stackTrace = new StackTrace(InvokeException(), fNeedFileInfo);
140-
VerifyFrames(stackTrace, fNeedFileInfo);
140+
VerifyFrames(stackTrace, fNeedFileInfo, 0);
141141
}
142142

143143
[Theory]
@@ -171,7 +171,7 @@ public void Ctor_Exception_SkipFrames(int skipFrames)
171171
Assert.Equal(expectedMethods, frames.Select(f => f.GetMethod()));
172172
if (frames != null)
173173
{
174-
VerifyFrames(stackTrace, false);
174+
VerifyFrames(stackTrace, false, skipFrames);
175175
}
176176
}
177177

@@ -211,7 +211,7 @@ public void Ctor_Exception_SkipFrames_FNeedFileInfo(int skipFrames, bool fNeedFi
211211
Assert.Equal(expectedMethods, frames.Select(f => f.GetMethod()));
212212
if (frames != null)
213213
{
214-
VerifyFrames(stackTrace, fNeedFileInfo);
214+
VerifyFrames(stackTrace, fNeedFileInfo, skipFrames);
215215
}
216216
}
217217

@@ -450,7 +450,7 @@ private class ClassWithConstructor
450450
public ClassWithConstructor() => StackTrace = new StackTrace();
451451
}
452452

453-
private static void VerifyFrames(StackTrace stackTrace, bool hasFileInfo)
453+
private static void VerifyFrames(StackTrace stackTrace, bool hasFileInfo, int skippedFrames)
454454
{
455455
Assert.True(stackTrace.FrameCount > 0);
456456

@@ -467,7 +467,11 @@ private static void VerifyFrames(StackTrace stackTrace, bool hasFileInfo)
467467
Assert.Equal(0, stackFrame.GetFileLineNumber());
468468
Assert.Equal(0, stackFrame.GetFileColumnNumber());
469469
}
470-
Assert.NotNull(stackFrame.GetMethod());
470+
471+
// On native AOT, the reflection invoke infrastructure uses compiler-generated code
472+
// that doesn't have a reflection method associated. Limit the checks.
473+
if (!PlatformDetection.IsNativeAot || (i + skippedFrames) == 0)
474+
Assert.NotNull(stackFrame.GetMethod());
471475
}
472476
}
473477
}

src/libraries/tests.proj

-1
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,6 @@
518518
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Data.Common\tests\System.Data.Common.Tests.csproj" />
519519
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Diagnostics.DiagnosticSource\tests\TestWithConfigSwitches\System.Diagnostics.DiagnosticSource.Switches.Tests.csproj" />
520520
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Diagnostics.PerformanceCounter\tests\System.Diagnostics.PerformanceCounter.Tests.csproj" />
521-
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Diagnostics.StackTrace\tests\System.Diagnostics.StackTrace.Tests.csproj" />
522521
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Diagnostics.TraceSource\tests\System.Diagnostics.TraceSource.Config.Tests\System.Diagnostics.TraceSource.Config.Tests.csproj" />
523522
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Diagnostics.Tracing\tests\System.Diagnostics.Tracing.Tests.csproj" />
524523
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Formats.Cbor\tests\System.Formats.Cbor.Tests.csproj" />

0 commit comments

Comments
 (0)