Skip to content

Crst Level violation: Can't take level 17 lock CrstLoaderAllocatorReferences #125638

Closed

Description

@EgorBo
Assert failure(PID 6052 [0x000017a4], Thread: 63069 [0xf65d]): Consistency check failed: Crst Level violation: Can't take level 17 lock CrstLoaderAllocatorReferences because you already holding level 14 lock CrstILStubGen

FAILED: false
    File: /Users/runner/work/1/s/src/coreclr/vm/crst.cpp:683
    Image: /private/tmp/helix/working/A6FA0928/p/dotnet

Build Information

Build: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1336431
Build error leg or test failing:

Error Message

Fill the error message using step by step known issues guidance.

{
  "ErrorMessage": "Consistency check failed: Crst Level violation: Can't take level 17 lock CrstLoaderAllocatorReferences because you already holding level 14 lock CrstILStubGen",
  "BuildRetry": false,
  "ExcludeConsoleLog": false
}

Known issue validation

Build: 🔎
Result validation: ⚠️ Validation could not be done without an Azure DevOps build URL on the issue. Please add it to the "Build: 🔎" line.
Validation performed at: 3/16/2026 11:03:35 PM UTC

Known issue validation

Build: 🔎
Result validation: ⚠️ Validation could not be done without an Azure DevOps build URL on the issue. Please add it to the "Build: 🔎" line.
Validation performed at: 3/16/2026 11:04:23 PM UTC

Known issue validation

Build: 🔎 https://dev.azure.com/dnceng-public/public/_build/results?buildId=1336431
Error message validated: [Consistency check failed: Crst Level violation: Can't take level 17 lock CrstLoaderAllocatorReferences because you already holding level 14 lock CrstILStubGen]
Result validation: ✅ Known issue matched with the provided build.
Validation performed at: 3/16/2026 11:05:48 PM UTC

Report

Build Definition Test Pull Request
1339071 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125226
1339093 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125335
1339024 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #123252
1338972 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #124893
1339048 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #124770
1338969 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125590
1338910 dotnet/runtime System.Net.NetworkInformation.Functional.Tests.WorkItemExecution #125645
1338932 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125647
1338929 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125646
1338866 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #124375
1338844 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #124766
1338825 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125525
1338820 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125643
1338751 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125196
1338761 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125500
1338767 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125386
1338690 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #123252
1338706 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #124375
1338649 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125636
1338624 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125594
1338633 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125531
1338637 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125519
1338555 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125545
1338582 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125640
1338529 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125571
1338428 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125251
1338601 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #124716
1338423 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125592
1336431 dotnet/runtime System.Net.Primitives.Pal.Tests.WorkItemExecution #125574

Summary

24-Hour Hit Count 7-Day Hit Count 1-Month Count
28 29 29

Activity

  1. changed the title [-]Consistency check failed: Crst Level violation: Can't take level 17 lock CrstLoaderAllocatorReferences because you already holding level 14 lock CrstILStubGen[/-] [+]Crst Level violation: Can't take level 17 lock CrstLoaderAllocatorReferences[/+] on Mar 16, 2026
  2. dotnet-policy-service commented on Mar 16, 2026

    @dotnet-policy-service
    Contributor

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

  3. dotnet-policy-service commented on Mar 16, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @agocke
    See info in area-owners.md if you want to be subscribed.

  4. jkotas commented on Mar 17, 2026

    @jkotas
    Member

    @EgorBo This was introduced by your PR #125574 .

  5. jkotas commented on Mar 17, 2026

    @jkotas
    Member

    Stacktrace of the assert:

    DbgAssertDialog
    CHECK::Trigger(char const*)
    CrstBase::IsSafeToTake()
    CrstBase::Enter(CrstBase::NoLevelCheckFlag)
    LoaderAllocator::EnsureInstantiation(Module*, Instantiation)
    ClassLoader::CreateTypeHandleForTypeDefThrowing(Module*, unsigned int, Instantiation, AllocMemTracker*)
    ClassLoader::CreateTypeHandleForTypeKey(TypeKey const*, AllocMemTracker*)
    ClassLoader::DoIncrementalLoad(TypeKey const*, TypeHandle, ClassLoadLevel)
    ClassLoader::LoadTypeHandleForTypeKey_Body(TypeKey const*, TypeHandle, ClassLoadLevel)
    ClassLoader::LoadTypeHandleForTypeKey(TypeKey const*, TypeHandle, ClassLoadLevel, InstantiationContext const*)
    ClassLoader::LoadConstructedTypeThrowing(TypeKey const*, ClassLoader::LoadTypesFlag, ClassLoadLevel, InstantiationContext const*)
    ClassLoader::LoadGenericInstantiationThrowing(Module*, unsigned int, Instantiation, ClassLoader::LoadTypesFlag, ClassLoadLevel, InstantiationContext const*, int)
    SigPointer::GetTypeHandleThrowing(ModuleBase*, SigTypeContext const*, ClassLoader::LoadTypesFlag, ClassLoadLevel, int, Substitution const*, ZapSig::Context const*, MethodTable*, SigPointer::HandleRecursiveGenericsForFieldLayoutLoad*) const
    MethodTableBuilder::InitializeFieldDescs(FieldDesc*, MethodTableBuilder::bmtInternalInfo*, MethodTableBuilder::bmtGenericsInfo const*, MethodTableBuilder::bmtMetaDataInfo*, MethodTableBuilder::bmtEnumFieldInfo*, MethodTableBuilder::bmtErrorInfo*, MethodTable***, MethodTableBuilder::bmtMethAndFieldDescs*, MethodTableBuilder::bmtFieldPlacement*, unsigned int*)
    MethodTableBuilder::BuildMethodTableThrowing(LoaderAllocator*, Module*, Module*, unsigned int, BuildingInterfaceInfo_t*, MethodTableBuilder::bmtLayoutInfo const*, MethodTable*, MethodTableBuilder::bmtGenericsInfo const*, SigPointer, unsigned short)
    ClassLoader::CreateTypeHandleForTypeDefThrowing(Module*, unsigned int, Instantiation, AllocMemTracker*)
    ClassLoader::CreateTypeHandleForTypeKey(TypeKey const*, AllocMemTracker*)
    ClassLoader::DoIncrementalLoad(TypeKey const*, TypeHandle, ClassLoadLevel)
    ClassLoader::LoadTypeHandleForTypeKey_Body(TypeKey const*, TypeHandle, ClassLoadLevel)
    ClassLoader::LoadTypeHandleForTypeKey(TypeKey const*, TypeHandle, ClassLoadLevel, InstantiationContext const*)
    ClassLoader::LoadTypeDefThrowing(Module*, unsigned int, ClassLoader::NotFoundAction, ClassLoader::PermitUninstantiatedFlag, unsigned int, ClassLoadLevel, Instantiation*)
    ClassLoader::LoadTypeDefOrRefThrowing(ModuleBase*, unsigned int, ClassLoader::NotFoundAction, ClassLoader::PermitUninstantiatedFlag, unsigned int, ClassLoadLevel)
    SigPointer::GetTypeHandleThrowing(ModuleBase*, SigTypeContext const*, ClassLoader::LoadTypesFlag, ClassLoadLevel, int, Substitution const*, ZapSig::Context const*, MethodTable*, SigPointer::HandleRecursiveGenericsForFieldLayoutLoad*)
    SigPointer::ConvertToInternalExactlyOne(Module*, SigTypeContext const*, SigBuilder*, int)
    unmanaged_name": "SigPointer::ConvertToInternalSignature(Module*, SigTypeContext const*, SigBuilder*, int)
    SigPointer::ConvertToInternalSignature(Module*, SigTypeContext const*, SigBuilder*, int)
    ILStubCache::CreateNewMethodDesc(LoaderHeap*, MethodTable*, unsigned int, Module*, unsigned char const*, unsigned int, int, SigTypeContext*, AllocMemTracker*)
    ILStubCache::GetStubMethodDesc(MethodDesc*, ILStubHashBlob*, unsigned int, Module*, Module*, unsigned char const*, unsigned int, SigTypeContext*, AllocMemTracker*, bool&, MethodDesc*)
    (anonymous namespace)::ILStubCreatorHelper::GetStubMethodDesc()
    (anonymous namespace)::CreateInteropILStub(ILStubState*, StubSigDesc*, CorNativeLinkType, CorNativeLinkFlags, CorInfoCallConvExtension, int, unsigned int*, int, bool*)
    PInvoke::CreateCLRToNativeILStub(StubSigDesc*, CorNativeLinkType, CorNativeLinkFlags, CorInfoCallConvExtension, unsigned int)
    PInvoke::GetStubForILStub(PInvokeMethodDesc*, MethodDesc**, unsigned int)
    GetStubForInteropMethod(MethodDesc*, unsigned int)
    MethodDesc::DoPrestub(MethodTable*, CallerGCMode)
    PreStubWorker
    ThePreStub
    System.Net.NetworkInformation.BsdNetworkInterface.GetBsdNetworkInterfaces()
    System.Net.NetworkInformation.NetworkInterfacePal.get_LoopbackInterfaceIndex()
    System.Net.NetworkInformation.NetworkInterfacePal.get_IPv6LoopbackInterfaceIndex()
    
  6. EgorBo commented on Mar 17, 2026

    @EgorBo
    MemberAuthor

    @EgorBo This was introduced by your PR #125574 .

    ouch 😞, definitely didn't expect a change in C# code to run into runtime lock asserts so didn't even check it, looking now

  7. jkotas commented on Mar 17, 2026

    @jkotas
    Member

    The changes exposed a pre-existing bug in the type loader. I think we want to do partial revert to get CI on track, and then take the time to implement a proper fix.

  8. EgorBo commented on Mar 17, 2026

    @EgorBo
    MemberAuthor

    @jkotas copilot says:

    Root cause: Debug_CanTake() in EnsureInstantiation/EnsureReference actually enters/leaves the CrstLoaderAllocatorReferences lock, triggering lock-level checks. When called during IL stub
    creation (which holds CrstILStubGen at level 14), the check fails because CrstLoaderAllocatorReferences is level 17. This fires even for non-collectible types that never actually take the
    lock.

    Changes (3 files, 8 lines):

    1. loaderallocator.cpp — Move _ASSERTE(Debug_CanTake()) after the IsCollectible() early-return checks in both EnsureReference and EnsureInstantiation, so the assert only fires when the
      lock will actually be taken.
    2. CrstTypes.def — Add ILStubGen to AcquiredAfter for LoaderAllocatorReferences, declaring the legitimate lock ordering: IL stub gen → type loading → loader allocator references.
    3. crsttypes_generated.h — Regenerated by CrstTypeTool. CrstILStubGen moves from level 14 to 18 (above CrstLoaderAllocatorReferences at 17).

    and sent the fix via #125675

    I'm not an expert to say if it's correct, though. From what I understand it sounds reasonable.

  9. added a commit that references this issue on Mar 18, 2026
    0389510
  10. locked and limited conversation to collaborators on Apr 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

  • Status
    No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions