Skip to content

Cannot unload a collectible AssemblyLoadContext if System.Data.SqlClient is used #414

@stasgaonkar

Description

@stasgaonkar

The Assembly we want to load (and unload) needs the ability to connect to a database for which we use Dapper. Dapper internally makes use of System.Data.SqlClient. We find that when we create such an assembly, then we are unable to Unload the collectible AssemblyLoadContext.

The sample source code is available at: https://github.com/stasgaonkar/DynamicLoading

Having followed the steps mentioned in https://docs.microsoft.com/en-us/dotnet/standard/assembly/unloadability#, the following is the output of gcroot command,

0:000> !dumpheap -type LoaderAllocator
         Address               MT     Size
000002022c46e1f0 00007fff74999410       48     
000002022c46e260 00007fff74999538       24     

Statistics:
              MT    Count    TotalSize Class Name
00007fff74999538        1           24 System.Reflection.LoaderAllocatorScout
00007fff74999410        1           48 System.Reflection.LoaderAllocator
Total 2 objects
0:000> !gcroot -all 0x000002022c46e1f0
HandleTable:
    000002022A9D12A0 (strong handle)
    -> 000002022C4E8C48 System.Data.SqlClient.TdsParserStateObjectNative
    -> 000002022C46E1F0 System.Reflection.LoaderAllocator

    000002022A9D12A8 (strong handle)
    -> 000002022C4E00F0 System.Data.SqlClient.TdsParserStateObjectNative
    -> 000002022C46E1F0 System.Reflection.LoaderAllocator

    000002022A9D12E0 (strong handle)
    -> 000002022C4B38C0 System.Data.SqlClient.TdsParserStateObjectNative
    -> 000002022C46E1F0 System.Reflection.LoaderAllocator

    000002022A9D15F8 (pinned handle)
    -> 000002023C461038 System.Object[]
    -> 000002022C475768 System.Threading.TimerQueue[]
    -> 000002022C475840 System.Threading.TimerQueue
    -> 000002022C4ABE88 System.Threading.TimerQueueTimer
    -> 000002022C475708 System.Threading.TimerQueueTimer
    -> 000002022C475580 System.Threading.TimerCallback
    -> 000002022C474D60 System.Data.SqlClient.SqlConnectionFactory
    -> 000002022C46E1F0 System.Reflection.LoaderAllocator

Found 4 roots.

So it seems that the TdsParserStateObjectNative is the culprit. What we have also noticed is that there are some "unmanaged/native DLL" that are used (sni.dll) internally by System.Data.SqlClient, possibly from within TdsParserStateObjectNative. Not sure if this is causing any issues.

Is something that we are attempting to do, incorrect?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions