diff --git a/debuggees.sln b/debuggees.sln index 565cc15669..28ecfb5ea3 100644 --- a/debuggees.sln +++ b/debuggees.sln @@ -47,6 +47,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debuggees", "Debuggees", "{ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VarargPInvokeInteropMD", "src\SOS\SOS.UnitTests\Debuggees\VarargPInvokeInteropMD\VarargPInvokeInteropMD.csproj", "{AE071195-19FD-4215-87A9-D4A77A4ACC52}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FindRootsOlderGeneration", "src\SOS\SOS.UnitTests\Debuggees\FindRootsOlderGeneration\FindRootsOlderGeneration.csproj", "{B7954E17-D190-42F2-B34F-284BCA70FD97}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DumpGCData", "src\SOS\SOS.UnitTests\Debuggees\DumpGCData\DumpGCData.csproj", "{CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Checked|Any CPU = Checked|Any CPU @@ -751,6 +755,86 @@ Global {AE071195-19FD-4215-87A9-D4A77A4ACC52}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU {AE071195-19FD-4215-87A9-D4A77A4ACC52}.RelWithDebInfo|x86.ActiveCfg = Debug|Any CPU {AE071195-19FD-4215-87A9-D4A77A4ACC52}.RelWithDebInfo|x86.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Checked|Any CPU.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Checked|ARM.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Checked|ARM.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Checked|ARM64.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Checked|ARM64.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Checked|x64.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Checked|x64.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Checked|x86.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Checked|x86.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Debug|ARM.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Debug|ARM.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Debug|ARM64.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Debug|x64.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Debug|x64.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Debug|x86.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Debug|x86.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Release|Any CPU.Build.0 = Release|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Release|ARM.ActiveCfg = Release|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Release|ARM.Build.0 = Release|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Release|ARM64.ActiveCfg = Release|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Release|ARM64.Build.0 = Release|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Release|x64.ActiveCfg = Release|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Release|x64.Build.0 = Release|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Release|x86.ActiveCfg = Release|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.Release|x86.Build.0 = Release|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.RelWithDebInfo|Any CPU.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.RelWithDebInfo|ARM.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.RelWithDebInfo|ARM.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.RelWithDebInfo|ARM64.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.RelWithDebInfo|ARM64.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.RelWithDebInfo|x86.ActiveCfg = Debug|Any CPU + {B7954E17-D190-42F2-B34F-284BCA70FD97}.RelWithDebInfo|x86.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Checked|Any CPU.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Checked|ARM.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Checked|ARM.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Checked|ARM64.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Checked|ARM64.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Checked|x64.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Checked|x64.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Checked|x86.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Checked|x86.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Debug|ARM.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Debug|ARM.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Debug|ARM64.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Debug|x64.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Debug|x64.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Debug|x86.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Debug|x86.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Release|Any CPU.Build.0 = Release|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Release|ARM.ActiveCfg = Release|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Release|ARM.Build.0 = Release|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Release|ARM64.ActiveCfg = Release|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Release|ARM64.Build.0 = Release|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Release|x64.ActiveCfg = Release|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Release|x64.Build.0 = Release|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Release|x86.ActiveCfg = Release|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.Release|x86.Build.0 = Release|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.RelWithDebInfo|Any CPU.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.RelWithDebInfo|ARM.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.RelWithDebInfo|ARM.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.RelWithDebInfo|ARM64.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.RelWithDebInfo|ARM64.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.RelWithDebInfo|x86.ActiveCfg = Debug|Any CPU + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5}.RelWithDebInfo|x86.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -777,6 +861,8 @@ Global {CC1781EF-A87B-E78E-5BE6-88998E9D9058} = {41638A4C-0DAF-47ED-A774-ECBBAC0315D7} {D25F6D55-E7B6-4231-F185-513E693BEEA2} = {CC1781EF-A87B-E78E-5BE6-88998E9D9058} {AE071195-19FD-4215-87A9-D4A77A4ACC52} = {D25F6D55-E7B6-4231-F185-513E693BEEA2} + {B7954E17-D190-42F2-B34F-284BCA70FD97} = {D25F6D55-E7B6-4231-F185-513E693BEEA2} + {CBE13BD1-EA24-4A95-818C-EE6FFA4F09A5} = {D25F6D55-E7B6-4231-F185-513E693BEEA2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {46465737-C938-44FC-BE1A-4CE139EBB5E0} diff --git a/src/Microsoft.Diagnostics.ExtensionCommands/RootCacheService.cs b/src/Microsoft.Diagnostics.ExtensionCommands/RootCacheService.cs index 4a8a860a55..f0b8226848 100644 --- a/src/Microsoft.Diagnostics.ExtensionCommands/RootCacheService.cs +++ b/src/Microsoft.Diagnostics.ExtensionCommands/RootCacheService.cs @@ -40,6 +40,8 @@ public class RootCacheService public bool IsDependentHandleLink(ulong source, ulong target) { + InitializeHandleRoots(); + int i = _dependentHandles.BinarySearch((source, target)); return i >= 0; } diff --git a/src/SOS/SOS.UnitTests/Debuggees/DumpGCData/DumpGCData.csproj b/src/SOS/SOS.UnitTests/Debuggees/DumpGCData/DumpGCData.csproj new file mode 100644 index 0000000000..644ea7fa32 --- /dev/null +++ b/src/SOS/SOS.UnitTests/Debuggees/DumpGCData/DumpGCData.csproj @@ -0,0 +1,7 @@ + + + Exe + $(BuildProjectFramework) + $(SupportedSubProcessTargetFrameworks) + + diff --git a/src/SOS/SOS.UnitTests/Debuggees/DumpGCData/Program.cs b/src/SOS/SOS.UnitTests/Debuggees/DumpGCData/Program.cs new file mode 100644 index 0000000000..7a74fe024d --- /dev/null +++ b/src/SOS/SOS.UnitTests/Debuggees/DumpGCData/Program.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace DumpGCData; + +internal class Program +{ + private static void Main() + { + Debugger.Break(); + + byte[] data = new byte[1024 * 1024]; + + GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); + GC.Collect(); + Debugger.Break(); + Console.WriteLine(handle.ToString()); + } +} diff --git a/src/SOS/SOS.UnitTests/Debuggees/FindRootsOlderGeneration/FindRootsOlderGeneration.csproj b/src/SOS/SOS.UnitTests/Debuggees/FindRootsOlderGeneration/FindRootsOlderGeneration.csproj new file mode 100644 index 0000000000..644ea7fa32 --- /dev/null +++ b/src/SOS/SOS.UnitTests/Debuggees/FindRootsOlderGeneration/FindRootsOlderGeneration.csproj @@ -0,0 +1,7 @@ + + + Exe + $(BuildProjectFramework) + $(SupportedSubProcessTargetFrameworks) + + diff --git a/src/SOS/SOS.UnitTests/Debuggees/FindRootsOlderGeneration/Program.cs b/src/SOS/SOS.UnitTests/Debuggees/FindRootsOlderGeneration/Program.cs new file mode 100644 index 0000000000..4b33905b1d --- /dev/null +++ b/src/SOS/SOS.UnitTests/Debuggees/FindRootsOlderGeneration/Program.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; +using System.Runtime; +using System.Runtime.InteropServices; + +namespace FindRootsOlderGeneration; + +internal class Program +{ + private static void Main() + { + Debugger.Break(); + + // Allocate a large object to ensure it goes on the LOH + Thing[] data = new Thing[1024 * 1024 * 3]; + int dataGen = GC.GetGeneration(data); + data[0] = new Thing() { Name = "First" }; + int thingGen = GC.GetGeneration(data[0]); + + Console.WriteLine("Enable CLRN notifications: SXE CLRN"); + Debugger.Break(); + + Console.WriteLine("Forcing GC..."); + GC.Collect(0, GCCollectionMode.Forced, true); + GC.Collect(0, GCCollectionMode.Forced, true); + Console.WriteLine("GC complete."); + Console.WriteLine("Disable CLRN notifications: SXN CLRN"); + Debugger.Break(); + + Console.WriteLine(data[0].Name); + Console.WriteLine($"Array Gen: {dataGen}, Thing Gen: {thingGen}"); + } +} + +internal class Thing +{ + public string Name { get; set; } +} diff --git a/src/SOS/SOS.UnitTests/SOS.cs b/src/SOS/SOS.UnitTests/SOS.cs index 17b89fdd04..3a66a4046f 100644 --- a/src/SOS/SOS.UnitTests/SOS.cs +++ b/src/SOS/SOS.UnitTests/SOS.cs @@ -35,6 +35,29 @@ public static IEnumerable GetNetCoreConfigurations() .Select(c => new[] { c }); } + public static IEnumerable GetGCConfigurations() + { + IEnumerable inputConfigurations = TestRunConfiguration.Instance.Configurations + // Filter out configurations for specific tests + .Where(c => c.AllSettings.GetValueOrDefault("TestName") == null) + // Filter for only .NET core configurations + .Where(c => c.IsNETCore) + // Filter out single file scenarios + .Where(c => !c.PublishSingleFile); + + TestConfiguration AddSetting(TestConfiguration inputConfiguration, string key, string value) + { + Dictionary settings = new(inputConfiguration.AllSettings); + settings.Add(key, value); + return new TestConfiguration(settings); + } + + IEnumerable outputConfigurations = inputConfigurations.Select(c => AddSetting(c, "GCServer", "0")) + .Concat(inputConfigurations.Select(c => AddSetting(c, "GCServer", "1"))); + + return outputConfigurations.Select(c => new[] { c }); + } + internal static void SkipIfArm(TestConfiguration config) { if (config.TargetArchitecture is "arm" or "arm64") @@ -229,6 +252,45 @@ await SOSTestHelpers.RunTest( testDump: false); } + [SkippableTheory, MemberData(nameof(SOSTestHelpers.GetGCConfigurations), MemberType = typeof(SOSTestHelpers))] + public async Task FindRootsOlderGeneration(TestConfiguration config) + { + if (OS.Kind != OSKind.Windows) + { + throw new SkipTestException("Test only supports CDB and therefore only runs on Windows"); + } + + if (config.RuntimeFrameworkVersionMajor < 10) + { + throw new SkipTestException("This test validates a bug which was fixed in .NET 10"); + } + + await SOSTestHelpers.RunTest( + config, + debuggeeName: "FindRootsOlderGeneration", + scriptName: "FindRootsOlderGeneration.script", + Output, + testName: "SOS.FindRootsOlderGeneration", + testDump: false); + } + + [SkippableTheory, MemberData(nameof(SOSTestHelpers.GetGCConfigurations), MemberType = typeof(SOSTestHelpers))] + public async Task DumpGCData(TestConfiguration config) + { + if (config.RuntimeFrameworkVersionMajor < 10) + { + throw new SkipTestException("This test validates a bug which was fixed in .NET 10"); + } + + await SOSTestHelpers.RunTest( + config, + debuggeeName: "DumpGCData", + scriptName: "DumpGCData.script", + Output, + testName: "SOS.DumpGCData", + testDump: false); + } + [SkippableTheory, MemberData(nameof(Configurations))] public async Task StackTraceSoftwareExceptionFrame(TestConfiguration config) { @@ -248,7 +310,7 @@ await SOSTestHelpers.RunTest( testTriage: true); } - [SkippableTheory, MemberData(nameof(Configurations)), Trait("Category", "CDACCompatible")] + [SkippableTheory, MemberData(nameof(Configurations))] public async Task StackTraceFaultingExceptionFrame(TestConfiguration config) { SOSTestHelpers.SkipIfWinX86(config); diff --git a/src/SOS/SOS.UnitTests/SOSRunner.cs b/src/SOS/SOS.UnitTests/SOSRunner.cs index 647bb08fb7..382a66bfe9 100644 --- a/src/SOS/SOS.UnitTests/SOSRunner.cs +++ b/src/SOS/SOS.UnitTests/SOSRunner.cs @@ -719,6 +719,18 @@ public static async Task StartDebugger(TestInformation information, D processRunner.WithEnvironmentVariable("DOTNET_DIAGNOSTIC_EXTENSIONS", extensions); } + string gcServerMode = config.GetValue("GCServer"); + if (!string.IsNullOrEmpty(gcServerMode)) + { + processRunner.WithEnvironmentVariable("DOTNET_gcServer", gcServerMode); + } + + string gcName = config.GetValue("GCName"); + if (!string.IsNullOrEmpty(gcName)) + { + processRunner.WithEnvironmentVariable("DOTNET_gcName", gcName); + } + DumpType? dumpType = null; if (action is DebuggerAction.LoadDump or DebuggerAction.LoadDumpWithDotNetDump) { @@ -866,6 +878,14 @@ public async Task RunScript(string scriptRelativePath) { throw new Exception($"Debugger command FAILED: {input}"); } + + } + // Switching threads is debugger specific and can cause issues + // with the runcommand helper. + else if (line.StartsWith("SWITCH_THREAD:")) + { + string input = line.Substring("SWITCH_THREAD:".Length).TrimStart(); + await SwitchThread(input); } else if (line.StartsWith("COMMAND_FAIL:")) { @@ -1107,6 +1127,31 @@ public async Task ContinueExecution() } } + public async Task SwitchThread(string threadId) + { + string command = null; + bool addPrefix = true; + + switch (Debugger) + { + case NativeDebugger.Cdb: + command = $"~{threadId}s"; + // Don't add the !runcommand prefix because it gets printed when cdb stops at + // the new thread because the helper extension used .pcmd to set a stop command. + addPrefix = false; + break; + default: + throw new NotImplementedException("Switching threads is not implemented on other debuggers"); + } + if (command != null) + { + if (!await RunCommand(command, addPrefix)) + { + throw new Exception($"'{command}' FAILED"); + } + } + } + public async Task RunSosCommand(string command, bool extensionCommand = false) { switch (Debugger) diff --git a/src/SOS/SOS.UnitTests/Scripts/DumpGCData.script b/src/SOS/SOS.UnitTests/Scripts/DumpGCData.script new file mode 100644 index 0000000000..b70b0f917f --- /dev/null +++ b/src/SOS/SOS.UnitTests/Scripts/DumpGCData.script @@ -0,0 +1,21 @@ +# +# Verifies DumpGCData command +# + +# Continue to the DebugBreak +CONTINUE +IFDEF:CDB +VERIFY:Break instruction exception - code 80000003 +ENDIF:CDB + +LOADSOS + +# At start of main, there should be no pinned objects +SOSCOMMAND:DumpGCData +VERIFY: pre and post pin: 0 + +CONTINUE + +# At second break, there should be a single pinned object +SOSCOMMAND:DumpGCData +VERIFY: pre and post pin: 1 \ No newline at end of file diff --git a/src/SOS/SOS.UnitTests/Scripts/FindRootsOlderGeneration.script b/src/SOS/SOS.UnitTests/Scripts/FindRootsOlderGeneration.script new file mode 100644 index 0000000000..b2fc007008 --- /dev/null +++ b/src/SOS/SOS.UnitTests/Scripts/FindRootsOlderGeneration.script @@ -0,0 +1,39 @@ +# +# Verifies that the !findroots command searches through older generations +# Test requires CDB for notifications +# Added for bug fixed in https://github.com/dotnet/runtime/pull/119396 +# + +# Continue to the DebugBreak +CONTINUE +VERIFY:Break instruction exception - code 80000003 + +LOADSOS + +CONTINUE + +# Call FindRoots to set up GCNotifications +SOSCOMMAND:FindRoots -gen any + +# Enable CLRN notifications +COMMAND:sxe CLRN + +# Should break on a GCNotification +CONTINUE + +# Print list of threads with their stacks + +SOSCOMMAND:clrstack -all + +# Switch to main runtime thread +SWITCH_THREAD:0 + +SOSCOMMAND:DumpStackObjects +VERIFY:\s*\s+\s+FindRootsOlderGeneration.Thing\s+ + +SOSCOMMAND:FindRoots \w+\s+()\s+(FindRootsOlderGeneration.Thing)(?!\[\]) +VERIFY:Found 1 unique roots. + +COMMAND:sxn CLRN + +CONTINUE \ No newline at end of file