Full repro
See https://github.com/elsand/npgsql-dapper-segfault/. The relevant code can also be found below.
Summary
A simple Dapper + Npgsql program crashes the process when binding an array parameter via ICustomQueryParameter and running SELECT unnest(@Ids). This happens on macOS (SIGSEGV, exit 139) and Windows (Fatal error. Internal CLR error 0x80131506). The repro targets net9.0 and net10.0 and uses Npgsql 10.0.1 + Dapper 2.1.66.
Crash seems to occur during Dapper parameter setup (before query execution) when NpgsqlParameter is created for an array via ICustomQueryParameter.
Not sure if this belongs here, or in https://github.com/dotnet/runtime, please advice. Assuming it's not Dapper, since that's only managed code (without unsafe/native interop).
Steps
- git clone https://github.com/elsand/npgsql-dapper-segfault/
- set PG_CONNECTION_STRING to a PostgreSQL instance
- dotnet run -f net10.0 (or -f net9.0)
Expected
Query returns the unnest’ed values.
Actual
Process crashes. On macOS it’s a SIGSEGV (exit 139). On Windows, it reports “Fatal error. Internal CLR error. (0x80131506)”.
Running on Mac gives no console output, unless minidumps are enabled:
DOTNET_DbgEnableMiniDump=1 \
DOTNET_DbgMiniDumpType=3 \
DOTNET_DbgMiniDumpName=/tmp/npgsql_segfault_%p.dmp \
PG_CONNECTION_STRING='Host=localhost;Database=postgres;Username=postgres;Password=xxxxxx' \
dotnet run -f net10.0
[createdump] Gathering state for process 51920
[createdump] Crashing thread 131147a signal 11 (000b)
[createdump] Writing triage minidump to file /tmp/npgsql_segfault_51920.dmp
[createdump] Written 38621464 bytes (2357 pages) to core file
[createdump] Target process is alive
[createdump] Dump successfully written in 197ms
Minidump can be provided upon request.
Running on Windows gives substantially more output:
PS C:\Users\bjorn\Repos\npgsql-dapper-segfault> dotnet run -f net10.0
Fatal error.
Internal CLR error. (0x80131506)
at Dapper.CommandDefinition.SetupCommand(System.Data.IDbConnection, System.Action`2<System.Data.IDbCommand,System.Object>)
at Dapper.SqlMapper.TrySetupAsyncCommand(Dapper.CommandDefinition, System.Data.IDbConnection, System.Action`2<System.Data.IDbCommand,System.Object>)
at Dapper.SqlMapper+<QueryAsync>d__33`1[[System.__Canon, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Dapper.SqlMapper+<QueryAsync>d__33`1[[System.__Canon, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Dapper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]](<QueryAsync>d__33`1<System.__Canon> ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.__Canon, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Start[[Dapper.SqlMapper+<QueryAsync>d__33`1[[System.__Canon, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Dapper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]](<QueryAsync>d__33`1<System.__Canon> ByRef)
at Dapper.SqlMapper.QueryAsync[[System.__Canon, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Data.IDbConnection, System.Type, Dapper.CommandDefinition)
at Dapper.SqlMapper.QueryAsync[[System.__Canon, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Data.IDbConnection, Dapper.CommandDefinition)
at Program+<<Main>$>d__0.MoveNext()
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[[System.Threading.Tasks.VoidTaskResult, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext(System.Threading.Thread)
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Runtime.CompilerServices.IAsyncStateMachineBox, Boolean)
at System.Threading.Tasks.Task.RunContinuations(System.Object)
at System.Threading.Tasks.Task`1[[System.Threading.Tasks.VoidTaskResult, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TrySetResult(System.Threading.Tasks.VoidTaskResult)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.Threading.Tasks.VoidTaskResult, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].SetExistingTaskResult(System.Threading.Tasks.Task`1<System.Threading.Tasks.VoidTaskResult>, System.Threading.Tasks.VoidTaskResult)
at Npgsql.NpgsqlConnection+<<Open>g__OpenAsync|42_0>d.MoveNext()
(rest of output omitted)
Full output of Windows run
Environment
- Hardware: Apple M3 Pro / AMD Ryzen 7 3700X
- OS: macOS 26.2 (Build 25C56) / Windows 11 Pro (Build 26200.7623)
- PostgreSQL: 16.10
- SDKs tested: .NET 9.0.310, .NET 10.0.102
- Packages: Npgsql 10.0.1, Dapper 2.1.66
Relevant code
using System.Data;
using Dapper;
using Npgsql;
await using var connection = new NpgsqlConnection(Environment.GetEnvironmentVariable("PG_CONNECTION_STRING")
?? "Host=localhost;Database=postgres;Username=postgres;Password=postgres");
await connection.OpenAsync();
var parameters = new
{
Ids = new PostgresArray<string>(["a"]) // Also tested with `int` and `Guid` type parameters - same result
};
var command = new CommandDefinition("SELECT unnest(@Ids) AS Value", parameters, cancellationToken: CancellationToken.None);
var rows = await connection.QueryAsync<string>(command); // <--- Segfault happens here
foreach (var value in rows) // <--- This line is never reached
{
Console.WriteLine(value);
}
internal readonly struct PostgresArray<T>(T[] value) : SqlMapper.ICustomQueryParameter
{
public void AddParameter(IDbCommand command, string name)
{
var param = new NpgsqlParameter(name, value);
command.Parameters.Add(param);
}
}
Full repro
See https://github.com/elsand/npgsql-dapper-segfault/. The relevant code can also be found below.
Summary
A simple Dapper + Npgsql program crashes the process when binding an array parameter via
ICustomQueryParameterand runningSELECT unnest(@Ids). This happens on macOS (SIGSEGV, exit 139) and Windows (Fatal error. Internal CLR error 0x80131506). The repro targets net9.0 and net10.0 and uses Npgsql 10.0.1 + Dapper 2.1.66.Crash seems to occur during Dapper parameter setup (before query execution) when
NpgsqlParameteris created for an array viaICustomQueryParameter.Not sure if this belongs here, or in https://github.com/dotnet/runtime, please advice. Assuming it's not Dapper, since that's only managed code (without unsafe/native interop).
Steps
Expected
Query returns the unnest’ed values.
Actual
Process crashes. On macOS it’s a SIGSEGV (exit 139). On Windows, it reports “Fatal error. Internal CLR error. (0x80131506)”.
Running on Mac gives no console output, unless minidumps are enabled:
Minidump can be provided upon request.
Running on Windows gives substantially more output:
Full output of Windows run
Environment
Relevant code