Skip to content

Follow-up diagnostics work for dynamic metadata-less types in .NET 11 #120800

Open

Description

@jakobbotsch

With #120411 merged and with DOTNET_RuntimeAsync=1 the runtime creates new dynamic Continuation MethodTables that do not have associated metadata. This issue captures diagnostics work required to support querying these.

Quoting @noahfalk from #120411 (comment):

  • All our APIs that expose object layouts do so in terms of metadata FieldDefs which we don't have here. At minimum we'd be breaking the assumption that the layout information is complete. If we wanted to go farther we could create new layout APIs that aren't backed by metadata tokens.
    Profiler API
    Debugger API

  • In the case of debugging, there is no API that enumerates GC references in an object separate from the layout API. We'd need to create that.

  • For debugging, profiling, and GCDumps emitted by events we have algorithms that do GC heap traversal. We'll need to ensure those algorithms are correctly handling these types (this may just fall out for free from the right GCDescs)

  • APIs that expose TypeDef tokens for types will need updates not to expose a token for these Continuation sub-types. The behavior change might need changes in the 3rd party tool code to accomodate for it. (ICorDebugClass::GetToken(), ICorProfilerInfo::GetClassIdInfo())

Also quoting @jkotas:

When designing these APIs, we should generalize them where possible to cover any no metadata types internally created by the runtime. We may want to use them for storing statics and get rid of static boxes.

These APIs may be useful for InlineArray types whose metadata does not convey their representation fully.

  • Profiler API not backed by metadata tokens
  • Debugger API not backed by metadata tokens
  • Debugger API to enumerate GC references in an object
  • GC heap traversal
    • Debugger
    • Profiler
    • GC dumps
  • ICorDebugClass::GetToken, ICorProfilerInfo::GetClassIdInfo fixes

Activity

  1. added
    needs-area-labelAn area label is needed to ensure this gets routed to the appropriate area owners
    on Oct 16, 2025
  2. added and removed
    untriagedNew issue has not been triaged by the area owner
    needs-area-labelAn area label is needed to ensure this gets routed to the appropriate area owners
    on Oct 16, 2025
  3. added this to the 11.0.0 milestone on Oct 16, 2025
  4. jakobbotsch commented on Oct 16, 2025

    @jakobbotsch
    MemberAuthor

    FWIW: I can certainly help with the design and implementation of these new APIs.

  5. dotnet-policy-service commented on Oct 16, 2025

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @steveisok, @dotnet/dotnet-diag
    See info in area-owners.md if you want to be subscribed.

  6. UtkarshBandekar commented on Jul 20, 2026

    @UtkarshBandekar
    Contributor

    I can reproduce a CoreCLR crash when a native profiler calls
    ICorProfilerInfo2::GetClassLayout() for a class encountered while a
    Runtime Async method is suspended.

    Environment

    • .NET SDK: 11.0.100-preview.6.26359.118
    • Runtime: Microsoft.NETCore.App 11.0.0-preview.6.26359.118
    • CoreCLR: 11.0.26.36018
    • OS: Windows x64
    • Runtime Async enabled with:
    <Features>runtime-async=on</Features>

    Scenario

    The test application contains an async method suspended on an incomplete
    Task. A managed object remains live across the await.

    A native profiler requests a full GC and processes the resulting heap
    information. When it queries the layout of one of the encountered
    classes using:

    ICorProfilerInfo2::GetClassLayout(...)

    the process terminates inside CoreCLR.

    Failure

    Internal CLR error: 0x80131506
    Exception: 0xC0000005
    Access violation reading location 0x0000000000000008
    Faulting module: coreclr.dll
    Fault offset: 0x000000000033464e
    

    The access violation occurs before GetClassLayout() returns an
    HRESULT.

    The same failure was reproduced from two independent profiler paths that
    query class layout.

    With Runtime Async disabled using:

    <UseRuntimeAsync>false</UseRuntimeAsync>

    the same application and heap-snapshot sequence complete successfully.

    This appears related to the dynamic continuation MethodTables without
    associated metadata described in this issue.

    Should GetClassLayout() return a defined failure for these continuation
    classes, or is another profiler API expected for identifying or querying
    their layout?

    I can provide a minimal application, native call stack, relevant
    ClassID values, and crash dump if needed.

  7. UtkarshBandekar commented on Jul 20, 2026

    @UtkarshBandekar
    Contributor

    Looking at the current implementation, the guard appears to be needed in:

    src/coreclr/vm/proftoeeinterfaceimpl.cpp
    ProfToEEInterfaceImpl::GetClassLayout()
    

    GetClassLayout() returns field information using metadata-backed
    FieldDef tokens. Runtime Async continuation types may not have this
    metadata, so the method should detect that case before creating or using
    ApproxFieldDescIterator.

    Suggested direction:

    TypeHandle typeHandle =
        TypeHandle::FromPtr((void*)classID);
    
    if (typeHandle.IsTypeDesc() ||
        typeHandle.AsMethodTable()->IsArray())
    {
        return E_INVALIDARG;
    }
    
    // Exact helper and HRESULT need confirmation.
    if (typeHandle.IsContinuationWithoutMetadata())
        {
            return CORPROF_E_DATAINCOMPLETE;
        }

    Could you confirm:

    1. What internal check should be used to identify a metadata-less
      continuation MethodTable?
    2. What HRESULT should GetClassLayout() return for this case?
    3. Should the existing API be guarded or is a new profiler API planned
      for retrieving layout information for these types?

    I do not have permission to create a branch or submit a PR, but I can
    validate a runtime build containing the agreed change.

  8. self-assigned this
    on Jul 21, 2026
  9. modified the milestones: 11.0.0, 12.0.0 on Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions