runtime: netcoreapp throws [recursive resource lookup bug] in combination with serilog

In combination with serilog some exception logging throws the following exception:

Assert Failure
Expression: [Recursive resource lookup bug]
Description: Infinite recursion during resource lookup within System.Private.CoreLib.  This may be a bug in System.Priva
te.CoreLib, or potentially in certain extensibility points such as assembly resolve events or CultureInfo names.  Resour
ce name: ArgumentNull_Generic
Stack Trace:
   at System.SR.InternalGetResourceString(String key)
   at System.SR.GetResourceString(String resourceKey, String defaultString)
   at System.ArgumentNullException..ctor(String paramName)
   at System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(Assembly assembly)
   at System.Reflection.Assembly.LoadFromResolveHandler(Object sender, ResolveEventArgs args)
   at System.AppDomain.OnAssemblyResolveEvent(RuntimeAssembly assembly, String assemblyFullName)
   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Runtim
eAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntro
spection, Boolean suppressSecurityChecks, IntPtr ptrLoadContextBinder)
   at System.Reflection.RuntimeAssembly.InternalGetSatelliteAssembly(String name, CultureInfo culture, Version version,
Boolean throwOnFileNotFound, StackCrawlMark& stackMark)
   at System.Resources.ManifestBasedResourceGroveler.GetSatelliteAssembly(CultureInfo lookForCulture, StackCrawlMark& st
ackMark)
   at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary`2 localResourc
eSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, B
oolean tryParents, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tr
yParents)
   at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
   at System.SR.InternalGetResourceString(String key)
   at System.SR.GetResourceString(String resourceKey, String defaultString)
   at System.ArgumentNullException..ctor(String paramName)
   at System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(Assembly assembly)
   at System.Reflection.Assembly.LoadFromResolveHandler(Object sender, ResolveEventArgs args)
   at System.AppDomain.OnAssemblyResolveEvent(RuntimeAssembly assembly, String assemblyFullName)
   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Runtim
eAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntro
spection, Boolean suppressSecurityChecks, IntPtr ptrLoadContextBinder)
   at System.Reflection.RuntimeAssembly.InternalGetSatelliteAssembly(String name, CultureInfo culture, Version version,
Boolean throwOnFileNotFound, StackCrawlMark& stackMark)
   at System.Resources.ManifestBasedResourceGroveler.GetSatelliteAssembly(CultureInfo lookForCulture, StackCrawlMark& st
ackMark)
   at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary`2 localResourc
eSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, B
oolean tryParents, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tr
yParents)
   at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
   at System.SR.InternalGetResourceString(String key)
   at System.SR.GetResourceString(String resourceKey, String defaultString)
   at System.IO.FileNotFoundException.ToString()
   at System.String.Concat(Object arg0, Object arg1)
   at Serilog.Formatting.Display.MessageTemplateTextFormatter.Format(LogEvent logEvent, TextWriter output)
   at Serilog.Sinks.RollingFileAlternate.Sinks.SizeRollingFileSink.SizeLimitedFileSink.Emit(LogEvent logEvent)
   at Serilog.Sinks.RollingFileAlternate.Sinks.SizeRollingFileSink.AlternateRollingFileSink.Emit(LogEvent logEvent)
   at Serilog.Core.Sinks.SafeAggregateSink.Emit(LogEvent logEvent)
   at Serilog.Core.Logger.Write(LogEventLevel level, Exception exception, String messageTemplate, Object[] propertyValue
s)
   at Serilog.Core.Logger.Error(Exception exception, String messageTemplate)
   at CodeTest.Program.Main(String[] args) in C:\git\MFCLib\CodeTest\Program.cs:line 17

Steps to reproduce: Project file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Serilog" Version="2.5.0" />
    <PackageReference Include="Serilog.Sinks.RollingFileAlternate" Version="2.0.9" />
  </ItemGroup>
</Project>

Program.cs:

using System;
using System.Reflection;
using Serilog;
using Serilog.Sinks.RollingFileAlternate;

namespace CodeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var logger = new LoggerConfiguration()
                    .WriteTo.RollingFileAlternate(".\\logs")
                    .CreateLogger();
            try
            {
                var libAssembly = Assembly.LoadFrom("lib.dll");
            }
            catch (Exception e)
            {
                logger.Error(e, "catch test {message}");
            }
        }
    }
}

One additional remark. When trying with other exceptions like division by zero the code works as expected.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 20 (10 by maintainers)

Most upvoted comments

@ltd65 this was https://github.com/dotnet/coreclr/issues/12668 which was fixed with https://github.com/dotnet/coreclr/pull/13003/files but unfortunately this missed the cutoff for the 2.0 release. We will try to service for it.

Meantime can you try this workaround. Put new ArgumentException(); on the first line of Main. Assuming that code runs before the Assembly.LoadFrom and other lookups, this should cause the neutral resources to be cached, avoiding the failure.

This avoids the crash for me (using the code above and putting CultureInfo.CurrentUICulture = new CultureInfo("de-CH"); to simulate machine culture)