Skip to content

Commit dad6f1e

Browse files
committed
Parse JSON and store the contracts
Until we get dotnet#101048 from codeflow, work around dotnet#101205 by adding a trimmer root for JsonDerivedTypeAttribute[].
1 parent 552aec4 commit dad6f1e

7 files changed

+54
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<linker>
2+
<assembly fullname="libcdacreader">
3+
<!-- https://github.com/dotnet/runtime/issues/101205 -->
4+
<type fullname="Microsoft.Diagnostics.DataContractReader.Root" preserve="all" />
5+
</assembly>
6+
</linker>

src/native/managed/cdacreader/src/ContractDescriptorParser.cs

+15-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public partial class ContractDescriptorParser
2929
}
3030

3131
[JsonSerializable(typeof(ContractDescriptor))]
32-
[JsonSerializable(typeof(int))]
32+
[JsonSerializable(typeof(int?))]
3333
[JsonSerializable(typeof(string))]
3434
[JsonSerializable(typeof(Dictionary<string, int>))]
3535
[JsonSerializable(typeof(Dictionary<string, TypeDescriptor>))]
@@ -38,11 +38,17 @@ public partial class ContractDescriptorParser
3838
[JsonSerializable(typeof(TypeDescriptor))]
3939
[JsonSerializable(typeof(FieldDescriptor))]
4040
[JsonSerializable(typeof(GlobalDescriptor))]
41+
[JsonSerializable(typeof(Dictionary<string, JsonElement>))]
4142
[JsonSourceGenerationOptions(AllowTrailingCommas = true,
4243
DictionaryKeyPolicy = JsonKnownNamingPolicy.Unspecified, // contracts, types and globals are case sensitive
4344
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
4445
NumberHandling = JsonNumberHandling.AllowReadingFromString,
45-
ReadCommentHandling = JsonCommentHandling.Skip)]
46+
ReadCommentHandling = JsonCommentHandling.Skip,
47+
UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip,
48+
UnknownTypeHandling = JsonUnknownTypeHandling.JsonElement,
49+
Converters = [typeof(TypeDescriptorConverter),
50+
typeof(FieldDescriptorConverter),
51+
typeof(GlobalDescriptorConverter)])]
4652
internal sealed partial class ContractDescriptorContext : JsonSerializerContext
4753
{
4854
}
@@ -58,7 +64,13 @@ public class ContractDescriptor
5864
public Dictionary<string, GlobalDescriptor>? Globals { get; set; }
5965

6066
[JsonExtensionData]
61-
public Dictionary<string, object?>? Extras { get; set; }
67+
public Dictionary<string, JsonElement>? Extras { get; set; }
68+
69+
public override string ToString()
70+
{
71+
return $"Version: {Version}, Baseline: {Baseline}, Contracts: {Contracts?.Count}, Types: {Types?.Count}, Globals: {Globals?.Count}";
72+
}
73+
6274
}
6375

6476
[JsonConverter(typeof(TypeDescriptorConverter))]
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Text.Json.Serialization;
5+
6+
namespace Microsoft.Diagnostics.DataContractReader;
7+
8+
internal static class Root
9+
{
10+
// https://github.com/dotnet/runtime/issues/101205
11+
public static JsonDerivedTypeAttribute[] R1 = new JsonDerivedTypeAttribute[] { null! };
12+
}

src/native/managed/cdacreader/src/Target.cs

+13-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Buffers.Binary;
6+
using System.Collections.Generic;
67

78
namespace Microsoft.Diagnostics.DataContractReader;
89

@@ -25,6 +26,7 @@ internal sealed unsafe class Target
2526
private int _pointerSize;
2627

2728
private TargetPointer[] _pointerData = [];
29+
private IReadOnlyDictionary<string, int> _contracts = new Dictionary<string, int>();
2830

2931
public Target(ulong contractDescriptor, delegate* unmanaged<ulong, byte*, uint, void*, int> readFromTarget, void* readContext)
3032
{
@@ -75,13 +77,23 @@ private void ReadContractDescriptor(ulong address)
7577
TargetPointer pointerData = ReadPointer(address);
7678

7779
// Read descriptor
78-
// TODO: [cdac] Pass to JSON parser
7980
Span<byte> descriptorBuffer = descriptorSize <= StackAllocByteThreshold
8081
? stackalloc byte[(int)descriptorSize]
8182
: new byte[(int)descriptorSize];
8283
if (ReadFromTarget(descriptor.Value, descriptorBuffer) < 0)
8384
throw new InvalidOperationException("Failed to read descriptor.");
8485

86+
ContractDescriptorParser.ContractDescriptor? targetDescriptor = ContractDescriptorParser.ParseCompact(descriptorBuffer);
87+
88+
if (targetDescriptor is null)
89+
{
90+
throw new InvalidOperationException("Failed to parse descriptor.");
91+
}
92+
93+
// TODO: [cdac] Read globals and types
94+
// note: we will probably want to store the globals and types into a more usable form
95+
_contracts = targetDescriptor.Contracts ?? new Dictionary<string, int>();
96+
8597
// Read pointer data
8698
_pointerData = new TargetPointer[pointerDataCount];
8799
for (int i = 0; i < pointerDataCount; i++)

src/native/managed/cdacreader/src/cdacreader.csproj

+5
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@
99
<!-- Do not produce a public package. This ships as part of the runtime -->
1010
<IsShippingPackage>false</IsShippingPackage>
1111
<InvariantGlobalization>true</InvariantGlobalization>
12+
<JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>
1213
</PropertyGroup>
1314

15+
<ItemGroup>
16+
<TrimmerRootDescriptor Include="CdacRoots.xml" />
17+
</ItemGroup>
18+
1419
<ItemGroup>
1520
<Compile Include="$(LibrariesProjectRoot)Common\src\System\HResults.cs" Link="Common\System\HResults.cs" />
1621
</ItemGroup>

src/native/managed/cdacreader/tests/ContractDescriptorParserTests.cs

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Text.Json;
56
using System.Text.Unicode;
67
using Xunit;
78

@@ -12,6 +13,7 @@ public class ContractDescriptorParserTests
1213
[Fact]
1314
public void ParsesEmptyContract()
1415
{
16+
Assert.False(JsonSerializer.IsReflectionEnabledByDefault);
1517
ReadOnlySpan<byte> json = "{}"u8;
1618
ContractDescriptorParser.ContractDescriptor descriptor = ContractDescriptorParser.ParseCompact(json);
1719
Assert.Null(descriptor.Version);

src/native/managed/cdacreader/tests/Microsoft.Diagnostics.DataContractReader.Tests.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<PropertyGroup>
33
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
44
<TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework>
5+
<JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>
56
</PropertyGroup>
67

78

0 commit comments

Comments
 (0)