Skip to content

Commit 41bb922

Browse files
Handle minimal MethodTables in dotnet-pgo trace processing (#127818)
BulkType ETW events emit `TypeNameID = th.GetCl()` (eventtrace_bulktype.cpp). For "minimal" MethodTables created by `CreateMinimalMethodTable` (used for Reflection.Emit DynamicMethod hosts in dynamicmethod.cpp and the IL stub cache in ilstubcache.cpp), `SetCl` is never called, so `GetCl` returns `mdTypeDefNil` (0x02000000, rid 0). dotnet-pgo previously treated this as a valid TypeDef token, and the lazy `EcmaType.Name` access would throw `BadImageFormatException: Read out of bounds` because rid 0 is before the typedef table. Validate the typedef row before constructing the `TypeDefinitionHandle` and treat out-of-range rids (rid 0, or rid greater than the typedef table size) as unresolvable dynamic types so trace processing can continue. This started failing on the SDK training pipeline after #126330 (Migrate CLR to COM stubs to be IL stubs) and #125352 (Move struct marshaling to transient IL) flowed through, which routed new categories of stubs through the minimal-MT path and added their BulkType events to the trace. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 30359c8 commit 41bb922

1 file changed

Lines changed: 12 additions & 1 deletion

File tree

src/coreclr/tools/dotnet-pgo/TraceRuntimeDescToTypeSystemDesc.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,18 @@ public TypeDesc ResolveTypeHandle(long handle, ref bool dependsOnKnownNonLoadabl
405405
throw new Exception($"Invalid typedef {tinfo.TypeValue.TypeNameID:4x}");
406406
}
407407

408-
TypeDefinitionHandle typedef = MetadataTokens.TypeDefinitionHandle(tinfo.TypeValue.TypeNameID & 0xFFFFFF);
408+
int typedefRow = tinfo.TypeValue.TypeNameID & 0xFFFFFF;
409+
// The runtime emits BulkType events for "minimal" MethodTables created by
410+
// CreateMinimalMethodTable in coreclr (used for Reflection.Emit DynamicMethod
411+
// hosts and the IL stub cache). These MTs have no typedef token and surface
412+
// here as TypeNameID == 0x02000000 (rid 0). Treat them as unresolvable
413+
// dynamic types so trace processing can continue.
414+
if (typedefRow == 0)
415+
{
416+
dependsOnKnownNonLoadableType = true;
417+
return null;
418+
}
419+
TypeDefinitionHandle typedef = MetadataTokens.TypeDefinitionHandle(typedefRow);
409420
MetadataType uninstantiatedType = (MetadataType)ecmaModule.GetType(typedef);
410421
// Instantiate the type if requested
411422
if ((tinfo.TypeValue.TypeParameters.Length != 0) && uninstantiatedType != null)

0 commit comments

Comments
 (0)