Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unobserved Task Exception(s) around DependencyInjection.ServiceLookup.get_ServiceType() #37337

Closed
jtbrower opened this issue Jun 3, 2020 · 14 comments · Fixed by #44675
Closed

Comments

@jtbrower
Copy link

jtbrower commented Jun 3, 2020

Description

Since upgrading a large enterprise app from NetCore 3.2 to .Net 5.0 Preview 4, I am seeing an unobserved exception being rethrown by the finalizer. It happens several times repeatedly every time I run my application, but it occurs all over the place and I cannot seem to trace it to one specific cause. For the most part, my application does not crash and it continues to run without issue.

I say "for the most part" because I am seeing another odd problem (likely unrelated) where 50% of the time debugging under visual studio the app appears both my app and Visual Studio are unresponsive. I think all of my Tasks have Try/Catches around them but this project is at 149 libraries as of today so its hard to say for certain. (Update : I think my deadlock could be related to #35986 "AddHttpClient" where the DI container is suspect. My lock happens right around the time I would be requesting the Client from the container. Related or not, they share a common root.)
The Stack Trace is always the Same

   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstantCallSite.get_ServiceType()
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstant(ConstantCallSite constantCallSite, ILEmitResolverBuilderContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitNoCache(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(ConstructorCallSite constructorCallSite, ILEmitResolverBuilderContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(ServiceCallSite callSite, ILGenerator generator)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.<.ctor>b__12_0(ServiceCacheKey key, ServiceCallSite cs)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitScopeCache(ServiceCallSite scopedCallSite, ILEmitResolverBuilderContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(ConstructorCallSite constructorCallSite, ILEmitResolverBuilderContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(ServiceCallSite callSite, ILGenerator generator)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.<.ctor>b__12_0(ServiceCacheKey key, ServiceCallSite cs)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitScopeCache(ServiceCallSite scopedCallSite, ILEmitResolverBuilderContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(ConstructorCallSite constructorCallSite, ILEmitResolverBuilderContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(ServiceCallSite callSite, ILGenerator generator)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.<.ctor>b__12_0(ServiceCacheKey key, ServiceCallSite cs)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitScopeCache(ServiceCallSite scopedCallSite, ILEmitResolverBuilderContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(ConstructorCallSite constructorCallSite, ILEmitResolverBuilderContext argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(ServiceCallSite callSite, ILGenerator generator)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.<.ctor>b__12_0(ServiceCacheKey key, ServiceCallSite cs)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.Build(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CompiledServiceProviderEngine.RealizeService(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>n__0(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__1()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__276_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)

Updated Information

I had a chance to focus more on this issue and started by disabling "just my code". The first code block below shows that the internal class "ConstantCallSite" allows a Null value as the DefaultValue, but neither of the overrides for "ServiceType" nor "ImplementationType" check "DefaultValue" for null before accessing them.

    internal class ConstantCallSite : ServiceCallSite
    {
        internal object DefaultValue { get; }

        public ConstantCallSite(Type serviceType, object defaultValue): base(ResultCache.None)
        {
            if (defaultValue != null && !serviceType.IsInstanceOfType(defaultValue))
            {
                throw new ArgumentException(SR.Format(SR.ConstantCantBeConvertedToServiceType, defaultValue.GetType(), serviceType));
            }
            //If null is a valid value then the code should be updated to check for null before the overrides use it.  If null is not a valid value
            //then  the parameter check statement above should be modified to throw, should it not?  -JTB
            DefaultValue = defaultValue;
        }

        public override Type ServiceType => DefaultValue.GetType();
        public override Type ImplementationType => DefaultValue.GetType();
        public override CallSiteKind Kind { get; } = CallSiteKind.Constant;
    }

I also included another stack trace that includes line numbers in the code.

Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstantCallSite.ServiceType.get() Line 23
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ConstantCallSite.cs(23)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstant(Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstantCallSite constantCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 190
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(190)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSiteMain(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 52
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(52)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitNoCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 64
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(64)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 35
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(35)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite constructorCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 154
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(154)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSiteMain(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 50
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(50)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, System.Reflection.Emit.ILGenerator generator) Line 361
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(361)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 105
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(105)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder..ctor.AnonymousMethod__12_0(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite cs) Line 62
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(62)
System.Collections.Concurrent.dll!System.Collections.Concurrent.ConcurrentDictionary<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod>.GetOrAdd<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite>(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, System.Func<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod> valueFactory, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite factoryArgument) Line 1069
	at /_/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs(1069)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 83
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(83)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitScopeCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite scopedCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 168
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(168)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 31
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(31)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite constructorCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 154
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(154)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSiteMain(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 50
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(50)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, System.Reflection.Emit.ILGenerator generator) Line 361
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(361)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 105
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(105)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder..ctor.AnonymousMethod__12_0(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite cs) Line 62
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(62)
System.Collections.Concurrent.dll!System.Collections.Concurrent.ConcurrentDictionary<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod>.GetOrAdd<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite>(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, System.Func<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod> valueFactory, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite factoryArgument) Line 1069
	at /_/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs(1069)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 83
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(83)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitScopeCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite scopedCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 168
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(168)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 31
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(31)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.VisitConstructor(Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite constructorCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 154
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(154)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext, object>.VisitCallSiteMain(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilderContext argument) Line 50
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs(50)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, System.Reflection.Emit.ILGenerator generator) Line 361
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(361)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildTypeNoCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 105
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(105)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder..ctor.AnonymousMethod__12_0(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite cs) Line 62
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(62)
System.Collections.Concurrent.dll!System.Collections.Concurrent.ConcurrentDictionary<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod>.GetOrAdd<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite>(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey key, System.Func<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GeneratedMethod> valueFactory, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite factoryArgument) Line 1069
	at /_/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs(1069)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.BuildType(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 83
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(83)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.Build(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 74
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ILEmit/ILEmitResolverBuilder.cs(74)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CompiledServiceProviderEngine.RealizeService(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite) Line 29
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CompiledServiceProviderEngine.cs(29)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.RealizeService.AnonymousMethod__1() Line 25
	at /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/DynamicServiceProviderEngine.cs(25)
System.Private.CoreLib.dll!System.Threading.Tasks.Task<System.Func<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, object>>.InnerInvoke() Line 498
	at /_/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs(498)
System.Private.CoreLib.dll!System.Threading.Tasks.Task..cctor.AnonymousMethod__276_0(object obj) Line 2353
	at /_/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs(2353)
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(System.Threading.Thread threadPoolThread, System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 289
	at /_/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs(289)
System.Private.CoreLib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot, System.Threading.Thread threadPoolThread) Line 2314
	at /_/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs(2314)
System.Private.CoreLib.dll!System.Threading.Tasks.Task.ExecuteEntryUnsafe(System.Threading.Thread threadPoolThread) Line 2252
	at /_/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs(2252)
System.Private.CoreLib.dll!System.Threading.Tasks.Task.ExecuteFromThreadPool(System.Threading.Thread threadPoolThread) Line 2237
	at /_/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs(2237)
System.Private.CoreLib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Line 659
	at /_/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs(659)
System.Private.CoreLib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() Line 29
	at /_/src/coreclr/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs(29)

I have an UnobservedTaskException handler catching this exception. The "sender" has the following information when I call "GetType()" using the Immediate Window in Visual Studio. My application continues to run regardless of me calling the SetObserved method on the UnobservedTaskExceptionEventArgs eventArgs object.

{Name = "Task`1" FullName = "System.Threading.Tasks.Task`1[[System.Func`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, Microsoft.Extensions.DependencyInjection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]"}
    Assembly: {System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e}
    AssemblyQualifiedName: "System.Threading.Tasks.Task`1[[System.Func`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, Microsoft.Extensions.DependencyInjection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
    Attributes: Public | BeforeFieldInit
    BaseType: {Name = "Task" FullName = "System.Threading.Tasks.Task"}
    Cache: {System.RuntimeType.RuntimeTypeCache}
    CacheIfExists: {System.RuntimeType.RuntimeTypeCache}
    ContainsGenericParameters: false
    CustomAttributes: Count = 4
    DeclaredConstructors: {System.Reflection.ConstructorInfo[15]}
    DeclaredEvents: {System.Reflection.EventInfo[0]}
    DeclaredFields: {System.Reflection.FieldInfo[2]}
    DeclaredMembers: {System.Reflection.MemberInfo[60]}
    DeclaredMethods: {System.Reflection.MethodInfo[37]}
    DeclaredNestedTypes: {System.Reflection.TypeInfo.<get_DeclaredNestedTypes>d__22}
    DeclaredProperties: {System.Reflection.PropertyInfo[5]}
    DeclaringMethod: '((System.RuntimeType)senderType).DeclaringMethod' threw an exception of type 'System.InvalidOperationException'
    DeclaringType: null
    DomainInitialized: false
    FullName: "System.Threading.Tasks.Task`1[[System.Func`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, Microsoft.Extensions.DependencyInjection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]"
    GUID: {56440075-ba51-37a6-9582-448a4f380bc0}
    GenericCache: null
    GenericParameterAttributes: '((System.RuntimeType)senderType).GenericParameterAttributes' threw an exception of type 'System.InvalidOperationException'
    GenericParameterPosition: '((System.RuntimeType)senderType).GenericParameterPosition' threw an exception of type 'System.InvalidOperationException'
    GenericTypeArguments: {System.Type[1]}
    GenericTypeParameters: {System.Type[0]}
    HasElementType: false
    ImplementedInterfaces: {System.Type[2]}
    IsAbstract: false
    IsAnsiClass: true
    IsArray: false
    IsAutoClass: false
    IsAutoLayout: true
    IsByRef: false
    IsByRefLike: false
    IsCOMObject: false
    IsClass: true
    IsCollectible: false
    IsConstructedGenericType: true
    IsContextful: false
    IsEnum: false
    IsExplicitLayout: false
    IsExportedToWindowsRuntime: false
    IsGenericMethodParameter: false
    IsGenericParameter: false
    IsGenericType: true
    IsGenericTypeDefinition: false
    IsGenericTypeParameter: false
    IsImport: false
    IsInterface: false
    IsLayoutSequential: false
    IsMarshalByRef: false
    IsNested: false
    IsNestedAssembly: false
    IsNestedFamANDAssem: false
    IsNestedFamORAssem: false
    IsNestedFamily: false
    IsNestedPrivate: false
    IsNestedPublic: false
    IsNotPublic: false
    IsPointer: false
    IsPrimitive: false
    IsPublic: true
    IsSZArray: false
    IsSealed: false
    IsSecurityCritical: true
    IsSecuritySafeCritical: false
    IsSecurityTransparent: false
    IsSerializable: false
    IsSignatureType: false
    IsSpecialName: false
    IsTypeDefinition: false
    IsUnicodeClass: false
    IsValueType: false
    IsVariableBoundArray: false
    IsVisible: false
    IsWindowsRuntimeObject: false
    MemberType: TypeInfo
    MetadataToken: 33555114
    Module (System.Reflection.MemberInfo): {System.Private.CoreLib.dll}
    Module: {System.Private.CoreLib.dll}
    Name: "Task`1"
    Namespace: "System.Threading.Tasks"
    ReflectedType: null
    StructLayoutAttribute: {System.Runtime.InteropServices.StructLayoutAttribute}
    TypeHandle: {System.RuntimeTypeHandle}
    TypeInitializer: {Void .cctor()}
    UnderlyingSystemType: {Name = "Task`1" FullName = "System.Threading.Tasks.Task`1[[System.Func`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope, Microsoft.Extensions.DependencyInjection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]"}
    m_cache: 0x1f399ea4
    m_handle: 0x1ffbabb8
    m_keepalive: null

Configuration

  • .Net 5.0 Preview 4
  • Windows 10 Pro for Workstations Build 18362.19h1_release.190318-1202
  • It happens when my app is built as both x86 and x64.

Regression?

I am 80% positive this did did not occur on .Net Core 3.2. I say 80% only because I have had so many distractions in my office lately that I could be mistaken when it began. Yet I know for a fact that I didn't notice it until I upgraded to .Net 5.0. I always run the app as an Exe (vs WinExe) so I have a console where I can see all of my logging live; thus I don't have to open a log file to be notified of the issue and am unlikely to overlook it.

Other information

The application is a point-of-sale touch-screen driven application with a pure MVVM architecture. It makes heavy use of Tasks and aysnc patterns where I am pretty anal about clean Task based coding such as no "async voids", no sync locking in async functions and etc. This is a complete ground-up re-write of an existing product so its currently all fresh code and plenty of mistakes are expected at this point; thus I could be doing something to cause this but from the looks of the stack trace it does not appear to be under my control.

If there is something special about my architecture that could agitate this bug it might be related to the hundreds of commands (ICommand) classes that are bound to buttons. I use a mediator pattern with a class that looks at an enum sent from the button press, maps that to an ICommand instance, probes the ICommand class to run the logic to see if it can be executed and based on that return value, it knows whether to execute the command synchronously or asynchronously. The majority of the commands are Task based. There is a lot of "awaiting" going on in this application and since it is also heavily dialog driven there can be more than one dispatcher thread running at times.

I will keep plugging away at this and update this report if I learn anything new.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label Jun 3, 2020
@Dotnet-GitSync-Bot
Copy link
Collaborator

I couldn't figure out the best area label to add to this issue. Please help me learn by adding exactly one area label.

@jtbrower
Copy link
Author

jtbrower commented Jun 3, 2020

I updated the issue with a second callstack that includes more useful information that I obtained after disabling "Just my Code".

@jtbrower
Copy link
Author

jtbrower commented Jun 5, 2020

Today I spent quite a bit more time tracking this issue down. Although the direct cause (other than the ConstantCallSite.DefaultValue null reference) is still alluding me, the following information may be useful.

In the hunt, I did some refactoring that would have changed task based timing. After this refactoring, I still hit the same type of exception, however it was then highly repeatable such that it happened on every boot at the exact same location unless I paused too long in the debugger, then it would not occur. The fact that I could hit it over and over again felt logical. Yet when I paused for a while, like 20 seconds, and then continued and did not hit the exception, I started to really get the feeling that this is timing related or maybe even interference from Visual Studio??

This time I tracked the issue down to a Transitive, Optional Constructor injected dependency that I did not provide an implementation for. However the DI container was throwing an exception, hitting that same null reference in the ConstantCallSite class unless I removed the optional parameter or gave the DI container an implementation for it. Note that when I initially reported this issue above, the container couldn't have been throwing the unobserved Task exception from this location because I was using that class to fetch my apps data. It was really hard to track it down when I first reported the issue because it was hitting the unobserved Task exception. After changing the code slightly it was more repeatable yet in a different manner.

Using the example below, I would add both class A and class B to the services collection, build the container and then request an instance of class A. I really don't know if this issue has anything at all to do with transitive dependencies but I included that fact since that was the reality of the situation. Note that after I narrowed this down, I created a small sample project to share BUT I couldn't reproduce the same error in the sample project. I did not kick off Tasks in the sample project and probably should have but I am really pressed for time and debugging the DI container is something I wish I could help with but I must focus on my own work.

public class A 
{
  public B B {get;}
  public A(B b)
  {
     B = b;
  }
}
public class B
{
  public Optional Optional {get;}
  
  public B(Optional? optional = null)
  {
    //The DI container would not provide me with an instance of class B unless
    //I paused at the debugger for a while, OR I removed the optional parameter
  }
}

If the ConstantCallSite.DefaultValue is updated to either throw an exception inside the constructor if null OR if null is a valid value then check it before dereferencing it, it might add a touch more clarity on this problem. However, I suspect the primary cause is elsewhere. It seems to be a timing issue. If I learn anything else I will update. For now, I am just going to provide an implementation for that optional parameter and hope that other timing changes do not cause the bug to show itself again.

@eerhardt eerhardt added this to the 5.0.0 milestone Jul 8, 2020
@eerhardt eerhardt removed the untriaged New issue has not been triaged by the area owner label Jul 8, 2020
@maryamariyan
Copy link
Member

Could you possibly send a reproducible project that we could clone and reproduce and if not, maybe you could consider sharing it privately. Because without reproducible code it would be hard to verify the problem/provide a fix.

@maryamariyan maryamariyan modified the milestones: 5.0.0, 6.0.0 Aug 20, 2020
@jtbrower
Copy link
Author

@maryamariyan It's been 3 months since I posted this :). I think that any software engineer could look at the extremely detailed information above and create a simple project from it. I included sample code classes in the details and even pointed Microsoft at the exact line of their code that needs to be corrected.

I like to try and help out but I also have plenty work of my own to do. I'm pretty confident in the Microsoft engineers and for that reason I'm sure they will know exactly what I am talking about. If not we have other problems.

@WolfspiritM
Copy link

WolfspiritM commented Nov 12, 2020

I'm having the same issue with an Aspnet Core application. I tried upgrading it from 3.1 to 5.0 and now visual studio throws exceptions when accessing certain controllers.

I tracked it down to the same problem which is a constructor for a transient service that expects an interface that I did not register but it has a default value set (null).

EDIT:
After testing even more I now found a very easy way to reproduce it:
https://gist.github.com/WolfspiritM/e16eb78772bca2856799ef17277bc117

I think the related PR that "broke" this is dotnet/extensions#2501

The reason why VS throws is that even so it's handled VS's default setting is to throw on NullRefernceException anyway.
I think it should be fixed cause it prevents code optimization via the ILEmitter

@Gannond0rf
Copy link

I am also having this issue with my Blazor Hosted WebAssembly app. it's using Identity Server and occurs after sign-in. Strange thing is that sign-in works perfectly the first time I get this error only after signing-out then signing-in again. Same thing null value in ConstantCallSite.DefaultValue. If I hit continue when the exception is thrown login proceeds as excepted. Further sign-in and sign-outs do not cause this error. Seems to be happening only the second time for me.

@WolfspiritM
Copy link

WolfspiritM commented Nov 13, 2020

@Gannond0rf Yep. The issue hit me with IdentityServer aswell. The reason is acutally this class of IdentityServer:
https://github.com/IdentityServer/IdentityServer4/blob/main/src/IdentityServer4/src/Services/Default/OidcReturnUrlParser.cs
(notice the IAuthorizationParametersMessageStore authorizationParametersMessageStore = null in the constructor)
When it creates an instance of:
https://github.com/IdentityServer/IdentityServer4/blob/main/src/IdentityServer4/src/Services/Default/DefaultIdentityServerInteractionService.cs which is used probably in an AccountService (for login/logoff) via IIdentityServerInteractionService.

As far as I understand the reason why it happens the second time is that on the second resolve of a service the DI Framework creates an optimized "path" to create the service (via a background worker) and stores that optimized version. This creation fails with a NullReferenceException and is actually caught via a try catch to swallow any exception. Every further resolving just uses the unoptimized version as the optimized version is never available.

Visual Studio per default has NullReferenceExceptions set to be thrown even so they're handled.
My workaround for now is to disable NullReferenceExceptions via Debug -> Windows -> Exception Settings -> Common Language Runtime Exceptions and I hope it's fixed soon.

Probably it also works to provide an instance of IAuthorizationParametersMessageStore.

@Gannond0rf
Copy link

@WolfspiritM thanks for the info, much appreciated. At least now I know it's not a problem with my project.

@WolfspiritM
Copy link

@maryamariyan Will this be merged into 5.x? As the milestone says 6.0? I'd rather not want to keep the null reference in VS unchecked the whole year.

@maryamariyan
Copy link
Member

maryamariyan commented Nov 18, 2020

@maryamariyan Will this be merged into 5.x? As the milestone says 6.0? I'd rather not want to keep the null reference in VS unchecked the whole year.

yes planning to port to 5.x as well.

UPDATE:
Refer to PR #44877

@D-Mellenthin
Copy link

@maryamariyan : I have the same problem as @WolfspiritM when using IdentityServer, but i'm still using (Asp) .NetCore 3.1.10 currently.
I'm not sure if the change that caused this problem was ported to any version of 3.1.X in the past, but it's annoying there as well, so it would be nice to consider a port to 3.1.X as well. The stack trace is pretty much the same, resulting in a NRE at Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstantCallSite.ServiceType.get().

@WolfspiritM
Copy link

@BloodyMettle Are you maybe using the 5.0 nuget package for Microsoft.Extensions.DependencyInjection? It's not directly related to dotnet 5 but to the nuget package.

@D-Mellenthin
Copy link

@WolfspiritM Thanks - we are normally using 3.1.10 but to be sure I checked all dependencies again... one dependency was unintentionally installed with the latest version, resulting in a dependecy on 5.0 ... seems like this did the trick, my former comment can be ignored :)

@ghost ghost locked as resolved and limited conversation to collaborators Jan 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.