Segmentation fault (core dumped) on Ubuntu 20.04 LTS when using C#, EF Core, Sqlite and NetTopology

Viewed 30

The following code works fine on Ubuntu 18.04 LTS, after using apt to install libc6-dev (required by another dependency) and libsqlite3-mod-spatialite on a fresh 18.04 instance. When running the same process with test console on 20.04.5 LTS I consistently get a Segmentation fault with a core dump.

I have found the following reference to core dumps mentioning PROJ (cartographic projection library used by spatialite) but no real actionable fixes: https://github.com/bricelam/mod_spatialite-NuGet

My project is a simple test console so I can isolate the behavior from other code: Project Structure

Project includes the following dependencies:

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.9">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.9" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.9" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite" Version="6.0.9" />
  </ItemGroup>

Program.cs simply creates context via helper, ensures schema was created and inserts 50 dummy records into a basic table.

using Microsoft.Data.Sqlite;

string filePath = "database.db";

SqliteConnectionStringBuilder scb = new SqliteConnectionStringBuilder()
{
    Pooling = false,
    DataSource = filePath
};

using (TestDataContext context = LocalContextFactory.CreateContext<TestDataContext>(scb.ConnectionString))
{
    context.Database.EnsureCreated();

    for (int i = 0; i < 50; i++)
    {
        Guid id = Guid.NewGuid();
        context.ObjectData.Add(new ObjectData() { ObjectUniqueId = id, Name = $"{id}" });
    }

    context.SaveChanges();
}

Console.WriteLine("Success");

Context has 2 entities defined:

using Microsoft.EntityFrameworkCore;

public class TestDataContext : DbContext
{
    public TestDataContext()
    {
    }

    public TestDataContext(DbContextOptions<TestDataContext> options) : base(options)
    {
    }

    public virtual DbSet<ObjectData> ObjectData { get; set; }
    public virtual DbSet<GeometryData> GeometryData { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ObjectData>(x => {
            x.HasKey(e => e.ObjectUniqueId);
            x.Property(p => p.ObjectUniqueId)
                .HasConversion(s => s.ToString(), s => new System.Guid(s));
        });

        modelBuilder.Entity<GeometryData>(x => {
            x.HasKey(e => e.ObjectUniqueId);
            x.Property(p => p.Geometry).HasSrid(4326);
            x.Property(p => p.ObjectUniqueId)
                .HasConversion(s => s.ToString(), s => new System.Guid(s));
        });

        base.OnModelCreating(modelBuilder);
    }
}

And those entities look like so:

using System.ComponentModel.DataAnnotations.Schema;

[Table("geometry_data")]
public class GeometryData
{

    [Column("object_unique_id")]
    public System.Guid ObjectUniqueId { get; set; }

    [Column("geometry_type_id")]
    public System.Int32 GeometryTypeId { get; set; }

    [Column("geometry")]
    public NetTopologySuite.Geometries.Geometry Geometry { get; set; }

}

[Table("object_data")]
public class ObjectData
{

    [Column("object_unique_id")]
    public System.Guid ObjectUniqueId { get; set; }

    [Column("object_name")]
    public string Name { get; set; }
}

Helper class for creating a local Sqlite dbContext with NetTopology enabled:

public static class LocalContextFactory
{
    public static TContext CreateContext<TContext>(string connectionString, bool useNetTopologyProvider = true) where TContext : DbContext
    {
        DbContextOptionsBuilder<TContext> optionsBuilder = new DbContextOptionsBuilder<TContext>();
        optionsBuilder.UseSqlite(connectionString, sqliteDbContextOptionBuilder =>
        {
            if (useNetTopologyProvider)
            {
                sqliteDbContextOptionBuilder.UseNetTopologySuite();
            }
        });

        optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
        TContext context = Activator.CreateInstance(typeof(TContext), optionsBuilder.Options) as TContext;

        return context;
    }
}
0 Answers
Related