Skip to content

Commit

Permalink
Fix GC heap dump (dotnet#38893)
Browse files Browse the repository at this point in the history
dotnet#36932 had a typo that caused types to never be logged
  • Loading branch information
davmason authored Jul 9, 2020
1 parent 919e683 commit 0716913
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/coreclr/src/vm/eventtrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3559,7 +3559,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 @@ -1625,6 +1625,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>

0 comments on commit 0716913

Please sign in to comment.