icu-dotnet icon indicating copy to clipboard operation
icu-dotnet copied to clipboard

Icu.Wrapper.Cleanup crash on net6 linux

Open FlipSs opened this issue 3 years ago • 6 comments

Hello! We are migrating to net6 and using this library in some projects. In net6 when calling Icu.Wrapper.Cleanup the application crashes with following: [7354115.440346] .NET ThreadPool[1337354]: segfault at 8 ip 00007f596b5e8d92 sp 00007f557effbb40 error 4 in libicui18n.so.67.1[7f596b53e000+17a000] This only happens on linux, we have tried debian 11, alpine, ubuntu and even debian 10 with the same version of libc6-dev as we used in net5 (which doesn't crash on net5).

Environment

  • OS: debian10/debian11/ubuntu/alpine
  • icu.net 2.8.1/2.7.1
  • net6

FlipSs avatar Oct 14 '22 10:10 FlipSs

Does it work with icu.net 2.9.0-beta which has added support for net6?

ermshiperete avatar Oct 17 '22 16:10 ermshiperete

Tried 2.9.0-beta.14 - same crash

FlipSs avatar Oct 18 '22 08:10 FlipSs

What classes and methods do you use? Do you have a small test case/project that demonstrates the crash?

ermshiperete avatar Oct 18 '22 13:10 ermshiperete

I was able to create a test project with minimal code that crashes only if Cleanup is called. I do not see how it is all connected and it seems crazy.

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using NUnit.Framework;

namespace MagicProject
{
	public class Startup
	{
		public void ConfigureServices(IServiceCollection services)
		{
		}

		public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
		{
		}
	}

	[Parallelizable]
	public class MagicTest
	{
		private IHost _testService;

		[OneTimeSetUp]
		public async Task SetUpAsync()
		{
			Icu.Wrapper.Init();

			var host = Host.CreateDefaultBuilder()
				.ConfigureWebHost(webHostBuilder =>
				{
					webHostBuilder
						.UseKestrel()
						.UseStartup<Startup>()
						.UseUrls("http://127.0.0.1:0")
						.UseContentRoot(Directory.GetCurrentDirectory());
				}).Build();

			using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)))
			{
				try
				{
					await host.StartAsync(cts.Token);
				}
				catch (OperationCanceledException)
				{
					throw new TimeoutException("Timed out waiting for application to start.");
				}
			}

			_testService = host;
		}

		[OneTimeTearDown]
		public async Task TearDownAsync()
		{
			if (_testService != null)
			{
				try
				{
					await _testService.StopAsync();
				}
				finally
				{
					_testService.Dispose();
				}
			}

			Icu.Wrapper.Cleanup();
		}

		[Test]
		public void Test()
		{
			var obj = JsonConvert.DeserializeObject<TestObject>("{\"Headers\":[{\"Key\":\"Accept\",\"Value\":[\"application/json, application/xml, application/x-www-form-urlencoded, application/x-ndjson\"]},{\"Key\":\"Host\",\"Value\":[\"127.0.0.1:40877\"]},{\"Key\":\"User-Agent\",\"Value\":[\"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36\"]},{\"Key\":\"Accept-Encoding\",\"Value\":[\"gzip, deflate\"]}]}");
			Console.WriteLine(JsonConvert.SerializeObject(obj));
			Assert.IsNotNull(obj);
		}

		private class TestObject
		{
			public Header[] Headers { get; set; }
		}

		private class Header
		{
			public string Key { get; set; }

			public string[] Value { get; set; }
		}
	}
}
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="icu.net" Version="2.8.1" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
    <PackageReference Include="NUnit" Version="3.13.3" />
    <PackageReference Include="Icu4c.Win.Full.Lib" Version="59.1.15" />
    <PackageReference Include="NUnit3TestAdapter" Version="4.2.1">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
</Project>

FlipSs avatar Oct 19 '22 10:10 FlipSs

@FlipSs Thanks, that was helpful!

Seems to be related to multi-threading and timing. If I add Thread.Sleep(1000) before calling Wrapper.Cleanup() the tests pass.

I fixed the bug in #176; could you please try the nuget package attached to the build of that PR to see if it fixes it for you?

ermshiperete avatar Oct 20 '22 12:10 ermshiperete

It seems to be working alright)

FlipSs avatar Oct 20 '22 13:10 FlipSs