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