Skip to content

Fix GC heap dump #38893

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/src/vm/eventtrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3560,7 +3560,7 @@ BOOL ETW::TypeSystemLog::AddTypeToGlobalCacheIfNotExists(TypeHandle th, BOOL * p
{
CrstHolder _crst(GetHashCrst());
// Like above, check if the type has been added from a different thread since we last looked it up.
if (pLoggedTypesFromModule->loggedTypesFromModuleHash.Lookup(th).th.IsNull())
if (!pLoggedTypesFromModule->loggedTypesFromModuleHash.Lookup(th).th.IsNull())
{
*pfCreatedNew = FALSE;
return fSucceeded;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/tests/issues.targets
Original file line number Diff line number Diff line change
Expand Up @@ -1707,6 +1707,9 @@
<ExcludeList Include="$(XunitTestBinBase)/tracing/tracevalidation/tracelogging/tracelogging/**">
<Issue>needs triage</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/tracing/eventpipe/gcdump/gcdump/**">
<Issue>needs triage</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/readytorun/coreroot_determinism/coreroot_determinism/**">
<Issue>needs triage</Issue>
</ExcludeList>
Expand Down
111 changes: 111 additions & 0 deletions src/coreclr/tests/src/tracing/eventpipe/gcdump/gcdump.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics.Tracing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.Diagnostics.NETCore.Client;
using Microsoft.Diagnostics.Tools.RuntimeClient;
using Microsoft.Diagnostics.Tracing;
using Microsoft.Diagnostics.Tracing.Parsers;
using Tracing.Tests.Common;
using Microsoft.Diagnostics.Tracing.Parsers.Clr;

namespace Tracing.Tests.EventSourceError
{
// Regression test for https://github.com/dotnet/runtime/issues/38639
public class GCDumpTest
{
private static int _bulkTypeCount = 0;
private static int _bulkNodeCount = 0;
private static int _bulkEdgeCount = 0;
private static int _bulkRootEdgeCount = 0;
private static int _bulkRootStaticVarCount = 0;

private static readonly ulong GC_HeapDump_Keyword = 0x100000UL;

public static int Main(string[] args)
{
// This test validates that if an EventSource generates an error
// during construction it gets emitted over EventPipe

List<Provider> providers = new List<Provider>
{
new Provider("Microsoft-Windows-DotNETRuntime", eventLevel: EventLevel.Verbose, keywords: (ulong)ClrTraceEventParser.Keywords.GCHeapSnapshot)
};

var configuration = new SessionConfiguration(circularBufferSizeMB: 1024, format: EventPipeSerializationFormat.NetTrace, providers: providers);
return IpcTraceTest.RunAndValidateEventCounts(_expectedEventCounts, _eventGeneratingAction, configuration, _DoesRundownContainMethodEvents);
}

private static Dictionary<string, ExpectedEventCount> _expectedEventCounts = new Dictionary<string, ExpectedEventCount>()
{
// This space intentionally left blank
};

private static Action _eventGeneratingAction = () =>
{
// This space intentionally left blank
};

private static Func<EventPipeEventSource, Func<int>> _DoesRundownContainMethodEvents = (source) =>
{
source.Clr.TypeBulkType += (GCBulkTypeTraceData data) =>
{
_bulkTypeCount += data.Count;
};

source.Clr.GCBulkNode += delegate (GCBulkNodeTraceData data)
{
_bulkNodeCount += data.Count;
};

source.Clr.GCBulkEdge += (GCBulkEdgeTraceData data) =>
{
_bulkEdgeCount += data.Count;
};

source.Clr.GCBulkRootEdge += (GCBulkRootEdgeTraceData data) =>
{
_bulkRootEdgeCount += data.Count;
};

source.Clr.GCBulkRootStaticVar += (GCBulkRootStaticVarTraceData data) =>
{
_bulkRootStaticVarCount += data.Count;
};

return () =>
{
// These values are ~80% (rounded to nice whole numbers) of the values
// I saw when writing the test. The idea is that I want to catch
// any real deviation in the number of types, but don't want to have
// to maintain this test as the number of types varies. (And they will vary due to
// framework code changes). If this test needs any sort of ongoing maintenance
// just change all these values to a low number like 10 and move on.
if (_bulkTypeCount > 125
&& _bulkNodeCount > 600
&& _bulkEdgeCount > 850
&& _bulkRootEdgeCount > 250
&& _bulkRootStaticVarCount > 70)
{
return 100;
}


Console.WriteLine($"Test failed due to missing GC heap events.");
Console.WriteLine($"_bulkTypeCount = {_bulkTypeCount}");
Console.WriteLine($"_bulkNodeCount = {_bulkNodeCount}");
Console.WriteLine($"_bulkEdgeCount = {_bulkEdgeCount}");
Console.WriteLine($"_bulkRootEdgeCount = {_bulkRootEdgeCount}");
Console.WriteLine($"_bulkRootStaticVarCount = {_bulkRootStaticVarCount}");
return -1;
};
};
}
}
14 changes: 14 additions & 0 deletions src/coreclr/tests/src/tracing/eventpipe/gcdump/gcdump.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
<OutputType>exe</OutputType>
<CLRTestKind>BuildAndRun</CLRTestKind>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<UnloadabilityIncompatible>true</UnloadabilityIncompatible>
<CLRTestPriority>0</CLRTestPriority>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
<ProjectReference Include="../common/common.csproj" />
</ItemGroup>
</Project>