Skip to content

Segmentation fault with NLog on linux-arm, related to "Recursive resource lookup bug"? #25403

@BrendanGrant

Description

@BrendanGrant

I had a dotnet core 2.0 app running fine on a Raspberry Pi 2 (running Raspbian) fine for many months, until the sd card gave up, so setup a new card with a fresh install of Raspbian & deployed an upgraded version (still targeting 2.0) with upgrades to the latest NuGet projects suddenly caused it to fail with the following error:

Assert Failure
Expression: [Recursive resource lookup bug]
Description: Infinite recursion during resource lookup within System.Private.CoreLib. This may be a bug in System.Private.CoreLib, or potentially in certain extensibility points such as assembly resolve events or CultureInfo names. Resource 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, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, 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& stackMark)
at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary2 localResourceSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark) at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark) at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents) 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, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, 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& stackMark) at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary2 localResourceSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark)
at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
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.SR.get_Arg_ArgumentException()
at PowerPi.Program.Main(String[] args) in C:\Users\grant\source\repos\PowerPi\PowerPi\Program.cs:line 22
Segmentation fault

This sounded rather similar to https://github.com/dotnet/corefx/issues/23608 (just one of many though), and using it's advice I created a new ArgumetnException() in my main to trigger it faster (as seen above in stacktrace).

Whittling things down into a standalone repro... I build a new stand alone project, added a NuGet reference to NLog.Extensions.Logging, added a NLog.config to the project which always copies to output directory, with the following contents:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target name="console" xsi:type="Console" />
  </targets>

  <rules>
    <logger name="*" minlevel="Info" writeTo="console" />
  </rules>
</nlog>

Then updated the Program.cs file to be the following:

using System;

namespace foo1
{
    class Program
    {
        static Logger logger = LogManager.GetLogger("GoingToCrash");
        static void Main(string[] args)
        {
            logger.Info("Hello World!");
            new ArgumentException();
            logger.Info("Boom?");
        }
    }
}

When I build/publish this demo app with:

dotnet publish --runtime linux-arm --configuration Release

To my Pi2... it fails with the above stacktrace. If I follow the advice of https://github.com/dotnet/corefx/issues/26292 and add the bolded text to the rather simple csproj:


  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>
***  <PropertyGroup>
    <RuntimeFrameworkVersion>2.0.5</RuntimeFrameworkVersion>
  </PropertyGroup>***

  <ItemGroup>
    <PackageReference Include="NLog.Extensions.Logging" Version="1.0.0-rtm-rc7" />
  </ItemGroup>

  <ItemGroup>
    <None Update="NLog.config">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>

</Project>

There is a slight improvement... it still suffers from a segmentation fault, only you don't see the stack trace.

Attached is the rather simplistic repro, which of course works fine on my Windows 10 machine, but fails on Raspbian GNU/Linux 9 (stretch).

Build environment details:

.NET Command Line Tools (2.1.100)

Product Information:
 Version:            2.1.100
 Commit SHA-1 hash:  b9e74c6520

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.16299
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\2.1.100\

Microsoft .NET Core Shared Framework Host

  Version  : 2.0.5
  Build    : 17373eb129b3b05aa18ece963f8795d65ef8ea54

coreclr-segfault-with-nlog-on-linux-arm.zip

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions