}
return start != end;
case GCGeneration.Generation2:
- if (!segment.IsLargeObjectSegment)
+ if (!(segment.IsLargeObjectSegment || segment.IsPinnedObjectSegment))
{
start = segment.Generation2.Start;
end = segment.Generation2.End;
end = segment.End;
}
return start != end;
+ case GCGeneration.PinnedObjectHeap:
+ if (segment.IsPinnedObjectSegment)
+ {
+ start = segment.Start;
+ end = segment.End;
+ }
+ return start != end;
default:
return false;
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using Microsoft.Diagnostics.Runtime;
+using System;
using System.Collections.Generic;
using System.Linq;
-using System;
+using Microsoft.Diagnostics.Runtime;
namespace Microsoft.Diagnostics.ExtensionCommands
{
-
public class DumpGen
{
private readonly ClrMDHelper _helper;
.Where(obj => obj.Type.MethodTable == methodTableAddress);
}
-
private static bool IsTypeNameMatching(string typeName, string typeNameFilter)
{
- return typeName.ToLower().Contains(typeNameFilter.ToLower());
+ return typeName.IndexOf(typeNameFilter, StringComparison.OrdinalIgnoreCase) >= 0;
}
-
}
-
}
return GCGeneration.Generation2;
case "loh":
return GCGeneration.LargeObjectHeap;
+ case "poh":
+ return GCGeneration.PinnedObjectHeap;
default:
- WriteLine($"{generation} is not a supported generation (gen0, gen1, gen2, loh)");
+ WriteLine($"{generation} is not a supported generation (gen0, gen1, gen2, loh, poh)");
return GCGeneration.NotSet;
}
}
- gen1
- gen2
- loh
+- poh
> dumpgen gen0
Statistics:
Generation0 = 1,
Generation1 = 2,
Generation2 = 3,
- LargeObjectHeap = 4
+ LargeObjectHeap = 4,
+ PinnedObjectHeap = 5
}
}
// This object should go into LOH
yield return new DumpSampleClass[50000];
+#if NET5_0_OR_GREATER
+ // This object should go into POH
+ yield return GC.AllocateUninitializedArray<byte>(10000, pinned: true);
+#endif
+
for (var i = 0; i < 5; i++)
{
yield return new DumpSampleClass();
public DateTime Date { get; set; }
}
-
public struct DumpSampleStruct
{
public int IntValue;
{
throw new SkipTestException("This test validates POH behavior, which was introduced in .net 5");
}
-
await RunTest(config, "GCPOH", "GCPOH.script", testName: "SOS.GCPOHTests", testDump: false);
}
TestName = "SOS.StackAndOtherTests",
DebuggeeName = "SymbolTestApp",
DebuggeeArguments = "%DEBUG_ROOT%",
+ DumpNameSuffix = currentConfig.DebugType
});
// This tests using regular Windows PDBs with no managed hosting. SOS should fallback
TestName = "SOS.StackAndOtherTests",
DebuggeeName = "SymbolTestApp",
DebuggeeArguments = "%DEBUG_ROOT%",
+ DumpNameSuffix = currentConfig.DebugType
});
}
}
DebuggeeArguments = desktopTestParameters,
UsePipeSync = true,
DumpGenerator = SOSRunner.DumpGenerator.DotNetDump
- }); ;
+ });
}
[SkippableTheory, MemberData(nameof(GetConfigurations), "TestName", "DotnetDumpCommands")]
TestConfiguration = config,
DebuggeeName = "DotnetDumpCommands",
DebuggeeArguments = "dcd",
+ DumpNameSuffix = "dcd",
UsePipeSync = true,
DumpGenerator = SOSRunner.DumpGenerator.DotNetDump,
- }); ;
+ });
}
[SkippableTheory, MemberData(nameof(GetConfigurations), "TestName", "DotnetDumpCommands")]
TestConfiguration = config,
DebuggeeName = "DotnetDumpCommands",
DebuggeeArguments = "dumpgen",
+ DumpNameSuffix = "dumpgen",
UsePipeSync = true,
DumpGenerator = SOSRunner.DumpGenerator.DotNetDump,
- }); ;
+ });
}
[SkippableTheory, MemberData(nameof(Configurations))]
public bool DumpDiagnostics { get; set; } = true;
+ public string DumpNameSuffix { get; set; }
+
public bool IsValid()
{
return TestConfiguration != null && OutputHelper != null && DebuggeeName != null;
TestConfiguration config = information.TestConfiguration;
string dumpRoot = action == DebuggerAction.GenerateDump ? config.DebuggeeDumpOutputRootDir() : config.DebuggeeDumpInputRootDir();
if (!string.IsNullOrEmpty(dumpRoot)) {
- return Path.Combine(dumpRoot, information.TestName + "." + information.DumpType.ToString() + ".dmp");
+ var sb = new StringBuilder();
+ sb.Append(information.TestName);
+ sb.Append(".");
+ sb.Append(information.DumpType.ToString());
+ if (information.DumpNameSuffix != null)
+ {
+ sb.Append(".");
+ sb.Append(information.DumpNameSuffix);
+ }
+ sb.Append(".dmp");
+ return Path.Combine(dumpRoot, sb.ToString());
}
return null;
}
COMMAND: dumpgen gen0
VERIFY: ^\s+MT\s+Count\s+TotalSize\s+Class Name
-VERIFY:^<HEXVAL>\s+10\s+<DECVAL>\s+DotnetDumpCommands\.Program\+DumpSampleClass
+VERIFY: ^<HEXVAL>\s+10\s+<DECVAL>\s+DotnetDumpCommands\.Program\+DumpSampleClass
COMMAND: dumpgen gen0 -type DotnetDumpCommands
VERIFY: ^<HEXVAL>\s+10\s+<DECVAL>\s+DotnetDumpCommands\.Program\+DumpSampleClass
COMMAND: dumpgen gen2
VERIFY: ^<HEXVAL>\s+5\s+<DECVAL>\s+DotnetDumpCommands\.Program\+DumpSampleClass
+!VERIFY: ^<HEXVAL>\s+1\s+100<DECVAL>\s+System.Byte\[\]
COMMAND: dumpgen loh
VERIFY: ^<HEXVAL>\s+1\s+<DECVAL>\s+DotnetDumpCommands\.Program\+DumpSampleClass\[\]
+IFDEF:MAJOR_RUNTIME_VERSION_GE_5
+COMMAND: dumpgen poh
+VERIFY: ^<HEXVAL>\s+1\s+100<DECVAL>\s+System.Byte\[\]
+ENDIF:MAJOR_RUNTIME_VERSION_GE_5
+
SOSCOMMAND: dumpheap -stat
ENDIF:NETCORE_OR_DOTNETDUMP