From 16b294f4118f9ea49199df09005b1f0936c55e5d Mon Sep 17 00:00:00 2001 From: Justin Anderson Date: Mon, 17 May 2021 15:04:55 -0700 Subject: [PATCH 1/3] Enable dump tests on Linux. --- .../TestConditions.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/TestConditions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/TestConditions.cs index 8b9b6567378..f412783d0f5 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/TestConditions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/TestConditions.cs @@ -13,10 +13,6 @@ public static bool IsDumpSupported { get { - // Linux dumps currently broken by https://github.com/dotnet/diagnostics/issues/2098 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - return false; - // MacOS supported dumps starting in .NET 5 if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && DotNetHost.RuntimeVersion.Major < 5) return false; From de2651410cd5c40b7854eef73120e0b11d2a4559 Mon Sep 17 00:00:00 2001 From: Justin Anderson Date: Mon, 17 May 2021 17:24:20 -0700 Subject: [PATCH 2/3] Add ELF types in order to read on Linux. --- .../DumpTests.cs | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/DumpTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/DumpTests.cs index 00a756174cd..d74cf69bfc6 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/DumpTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/DumpTests.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.FileFormats; using Microsoft.FileFormats.ELF; +using System; using System.IO; using System.Net.Http; using System.Runtime.InteropServices; @@ -103,7 +104,26 @@ await appRunner.ExecuteAsync(async () => // Validate Signature Assert.True(header.IsSignatureValid.Check()); } - else + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + ELFHeaderIdent ident = dumpReader.Read(0); + Assert.True(ident.IsIdentMagicValid.Check()); + Assert.True(ident.IsClassValid.Check()); + Assert.True(ident.IsDataValid.Check()); + + LayoutManager layoutManager = new(); + layoutManager.AddELFTypes( + isBigEndian: ident.Data == ELFData.BigEndian, + is64Bit: ident.Class == ELFClass.Class64); + Reader headerReader = new(dumpAddressSpace, layoutManager); + + ELFHeader header = headerReader.Read(0); + // Validate Signature + Assert.True(header.IsIdentMagicValid.Check()); + // Validate ELF file is a core dump + Assert.Equal(ELFHeaderType.Core, header.Type); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { ELFHeader header = dumpReader.Read(0); // Validate Signature @@ -111,6 +131,10 @@ await appRunner.ExecuteAsync(async () => // Validate ELF file is a core dump Assert.Equal(ELFHeaderType.Core, header.Type); } + else + { + throw new NotImplementedException("Dump header check not implemented for this OS platform."); + } await appRunner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue); }); From 1fa11b75b7c26d323dd77c86133ed9bb7f10bee3 Mon Sep 17 00:00:00 2001 From: Justin Anderson Date: Mon, 17 May 2021 17:59:28 -0700 Subject: [PATCH 3/3] Enable Mach-O dump header verification for .NET 6 Increase dump timeout. Fix RuntimeVersion parsing. --- .../DotNetHost.cs | 4 ++- .../DumpTests.cs | 33 ++++++++++++++----- .../HttpApi/ApiClientExtensions.cs | 2 +- .../TestTimeouts.cs | 5 +++ 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/DotNetHost.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/DotNetHost.cs index e074b6c2454..075ae74b3cb 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/DotNetHost.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/DotNetHost.cs @@ -9,8 +9,10 @@ namespace Microsoft.Diagnostics.Monitoring.TestCommon { public partial class DotNetHost { + // The version is in the Major.Minor.Patch-label format; remove the label + // and only parse the Major.Minor.Patch part. private static Lazy s_runtimeVersionLazy = - new(() => Version.Parse(CurrentNetCoreVersionString)); + new(() => Version.Parse(CurrentNetCoreVersionString.Split("-")[0])); public static Version RuntimeVersion => s_runtimeVersionLazy.Value; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/DumpTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/DumpTests.cs index d74cf69bfc6..a2e4a4a7779 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/DumpTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/DumpTests.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.FileFormats; using Microsoft.FileFormats.ELF; +using Microsoft.FileFormats.MachO; using System; using System.IO; using System.Net.Http; @@ -25,6 +26,8 @@ namespace Microsoft.Diagnostics.Monitoring.UnitTests [Collection(DefaultCollectionFixture.Name)] public class DumpTests { + private const string EnableElfDumpOnMacOS = "COMPlus_DbgEnableElfDumpOnMacOS"; + private readonly IHttpClientFactory _httpClientFactory; private readonly ITestOutputHelper _outputHelper; @@ -66,10 +69,10 @@ public async Task DumpTest(DiagnosticPortConnectionMode mode, DumpType type) appRunner.DiagnosticPortPath = diagnosticPortPath; appRunner.ScenarioName = TestAppScenarios.AsyncWait.Name; - // MachO not supported, only ELF: https://github.com/dotnet/runtime/blob/main/docs/design/coreclr/botr/xplat-minidump-generation.md#os-x - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + // MachO not supported on .NET 5, only ELF: https://github.com/dotnet/runtime/blob/main/docs/design/coreclr/botr/xplat-minidump-generation.md#os-x + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && DotNetHost.RuntimeVersion.Major == 5) { - appRunner.Environment.Add("COMPlus_DbgEnableElfDumpOnMacOS", "1"); + appRunner.Environment.Add(EnableElfDumpOnMacOS, "1"); } await appRunner.ExecuteAsync(async () => @@ -85,7 +88,7 @@ await appRunner.ExecuteAsync(async () => // Read enough to deserialize the header. int read; int total = 0; - using CancellationTokenSource cancellation = new(TestTimeouts.HttpApi); + using CancellationTokenSource cancellation = new(TestTimeouts.DumpTimeout); while (total < headerBuffer.Length && 0 != (read = await holder.Stream.ReadAsync(headerBuffer, total, headerBuffer.Length - total, cancellation.Token))) { total += read; @@ -125,11 +128,23 @@ await appRunner.ExecuteAsync(async () => } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { - ELFHeader header = dumpReader.Read(0); - // Validate Signature - Assert.True(header.IsIdentMagicValid.Check()); - // Validate ELF file is a core dump - Assert.Equal(ELFHeaderType.Core, header.Type); + if (appRunner.Environment.ContainsKey(EnableElfDumpOnMacOS)) + { + ELFHeader header = dumpReader.Read(0); + // Validate Signature + Assert.True(header.IsIdentMagicValid.Check()); + // Validate ELF file is a core dump + Assert.Equal(ELFHeaderType.Core, header.Type); + } + else + { + MachHeader header = dumpReader.Read(0); + // Validate Signature + Assert.True(header.IsMagicValid.Check()); + // Validate MachO file is a core dump + Assert.True(header.IsFileTypeValid.Check()); + Assert.Equal(MachHeaderFileType.Core, header.FileType); + } } else { diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/HttpApi/ApiClientExtensions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/HttpApi/ApiClientExtensions.cs index 719658216df..6b5af127eea 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/HttpApi/ApiClientExtensions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/HttpApi/ApiClientExtensions.cs @@ -103,7 +103,7 @@ public static async Task> GetProcessEnvironmentAsync( /// public static Task CaptureDumpAsync(this ApiClient client, int pid, DumpType dumpType) { - return client.CaptureDumpAsync(pid, dumpType, TestTimeouts.HttpApi); + return client.CaptureDumpAsync(pid, dumpType, TestTimeouts.DumpTimeout); } /// diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/TestTimeouts.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/TestTimeouts.cs index 9adbf9d4809..68cb7fedd93 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/TestTimeouts.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTests/TestTimeouts.cs @@ -32,5 +32,10 @@ internal static class TestTimeouts /// Default logs collection duration. /// public static readonly TimeSpan LogsDuration = TimeSpan.FromSeconds(10); + + /// + /// Default timeout for dump collection. + /// + public static readonly TimeSpan DumpTimeout = TimeSpan.FromMinutes(1); } }