firebird icon indicating copy to clipboard operation
firebird copied to clipboard

Thread hang when multiple Windows 11 processes write concurrently to same embedded Firebird 5.0.1 DB

Open nir-moshe opened this issue 2 months ago • 5 comments

Hello, I’m using Firebird 5.0.1 in embedded mode on Windows, together with the official .NET Firebird client (FirebirdSql.Data.FirebirdClient).

The problem: Occasionally, one of the threads becomes permanently stuck during execution. This happens frequently on Windows 11 (approximately once every 200 runs), but only rarely occurred on Windows 10 under the same configuration.

Notes: The thread appears to hang inside SharedMemoryBase::eventWait() in isc_sync.cpp. No exceptions or errors appear in Firebird logs or on the client side.

Is this a known issue? Is there a recommended configuration or locking strategy to avoid this?

Environment: OS: Windows 11 Pro 64-bit Firebird version: 5.0.1 (embedded) Client: Firebird .NET Data Provider (FirebirdSql.Data.FirebirdClient, version — please specify if known) Programming language: C# (.NET 8) Database: Local .fdb file, not shared over network

firebird.conf: ServerMode = SuperClassic

Connection string: Charset=UNICODE_FSS;clientlibrary={Path_to_fbembed.dll}; ServerType=1;Dialect=3; User={user};Password={password}; Database={dbpath}; Pooling=true;MinPoolSize=0;MaxPoolSize=100;Connection lifetime=15;

Setup and configuration are as follows: Two separate Windows processes, each using multiple threads that write to the same database file. The database is stored on a local disk (not a network share).

StackTrace: ntdll.dll!_NtWaitForSingleObject@12() KERNELBASE.dll!WaitForSingleObjectEx() KERNELBASE.dll!_WaitForSingleObject@8() engine13.dll!Firebird::SharedMemoryBase::eventWait(Firebird::event_t * event, const long value, const long micro_seconds) Line 748 at C:\firebird-build\src\common\isc_sync.cpp(748) engine13.dll!Jrd::LockManager::wait_for_request(Jrd::thread_db * tdbb, lrq * request, short lck_wait) Line 3826 at C:\firebird-build\src\lock\lock.cpp(3826) [Inline Frame] engine13.dll!Jrd::LockManager::grant_or_que(Jrd::thread_db * request, lrq ) Line 2203 at C:\firebird-build\src\lock\lock.cpp(2203) engine13.dll!Jrd::LockManager::enqueue(Jrd::thread_db * tdbb, Firebird::CheckStatusWrapper * statusVector, long prior_request, const unsigned short series, const unsigned char * value, const unsigned short length, unsigned char type, int()(void *) ast_routine, void * ast_argument, __int64 data, short lck_wait, long owner_offset) Line 531 at C:\firebird-build\src\lock\lock.cpp(531) [Inline Frame] engine13.dll!enqueue(Jrd::thread_db * tdbb, Firebird::CheckStatusWrapper *) Line 949 at C:\firebird-build\src\jrd\lck.cpp(949) [Inline Frame] engine13.dll!ENQUEUE(Jrd::thread_db *) Line 149 at C:\firebird-build\src\jrd\lck.cpp(149) engine13.dll!LCK_lock(Jrd::thread_db * tdbb, Jrd::Lock * lock, unsigned short level, short wait) Line 675 at C:\firebird-build\src\jrd\lck.cpp(675) engine13.dll!LCK_lock_opt(Jrd::thread_db * tdbb, Jrd::Lock * lock, unsigned short level, short wait) Line 732 at C:\firebird-build\src\jrd\lck.cpp(732) engine13.dll!lock_buffer(Jrd::thread_db * tdbb, Jrd::BufferDesc * bdb, const short wait, const char page_type) Line 4128 at C:\firebird-build\src\jrd\cch.cpp(4128) engine13.dll!CCH_fetch_lock(Jrd::thread_db * tdbb, Jrd::win * window, int lock_type, int wait, char page_type) Line 894 at C:\firebird-build\src\jrd\cch.cpp(894) engine13.dll!CCH_fetch(Jrd::thread_db * tdbb, Jrd::win * window, int lock_type, char page_type, int wait, const bool read_shadow) Line 801 at C:\firebird-build\src\jrd\cch.cpp(801) [Inline Frame] engine13.dll!CCH_FETCH(Jrd::thread_db *) Line 84 at C:\firebird-build\src\jrd\cch_proto.h(84) engine13.dll!DPM_get(Jrd::thread_db * tdbb, Jrd::record_param * rpb, short lock_type) Line 1635 at C:\firebird-build\gen\jrd\dpm.cpp(1635) engine13.dll!VIO_get(Jrd::thread_db * tdbb, Jrd::record_param * rpb, Jrd::jrd_tra * transaction, Firebird::MemoryPool * pool) Line 2948 at C:\firebird-build\src\jrd\vio.cpp(2948) engine13.dll!Jrd::BitmapTableScan::internalGetRecord(Jrd::thread_db * tdbb) Line 113 at C:\firebird-build\src\jrd\recsrc\BitmapTableScan.cpp(113) engine13.dll!Jrd::RecordSource::getRecord(Jrd::thread_db * tdbb) Line 79 at C:\firebird-build\src\jrd\recsrc\RecordSource.cpp(79) engine13.dll!Jrd::FilteredStream::evaluateBoolean(Jrd::thread_db * tdbb) Line 381 at C:\firebird-build\src\jrd\recsrc\FilteredStream.cpp(381) engine13.dll!Jrd::FilteredStream::internalGetRecord(Jrd::thread_db * tdbb) Line 111 at C:\firebird-build\src\jrd\recsrc\FilteredStream.cpp(111) engine13.dll!Jrd::RecordSource::getRecord(Jrd::thread_db * tdbb) Line 79 at C:\firebird-build\src\jrd\recsrc\RecordSource.cpp(79) engine13.dll!Jrd::Cursor::fetchNext(Jrd::thread_db * tdbb) Line 255 at C:\firebird-build\src\jrd\recsrc\Cursor.cpp(255) engine13.dll!Jrd::ForNode::execute(Jrd::thread_db * tdbb, Jrd::Request * request, Jrd::StmtNode::ExeState * __formal) Line 5232 at C:\firebird-build\src\dsql\StmtNodes.cpp(5232) engine13.dll!EXE_looper(Jrd::thread_db * tdbb, Jrd::Request * request, const Jrd::StmtNode * node) Line 1458 at C:\firebird-build\src\jrd\exe.cpp(1458) engine13.dll!looper_seh(Jrd::thread_db * tdbb, Jrd::Request * request, const Jrd::StmtNode * node) Line 1588 at C:\firebird-build\src\jrd\exe.cpp(1588) engine13.dll!execute_looper(Jrd::thread_db * tdbb, Jrd::Request * request, Jrd::jrd_tra * transaction, const Jrd::StmtNode * node, Jrd::Request::req_s next_state) Line 1071 at C:\firebird-build\src\jrd\exe.cpp(1071) engine13.dll!EXE_send(Jrd::thread_db * tdbb, Jrd::Request * request, unsigned short msg, unsigned long length, const void * buffer) Line 830 at C:\firebird-build\src\jrd\exe.cpp(830) engine13.dll!MET_procedure(Jrd::thread_db * tdbb, unsigned short id, bool noscan, unsigned short flags) Line 8651 at C:\firebird-build\gen\jrd\met.cpp(8651) engine13.dll!MET_lookup_procedure_id(Jrd::thread_db * tdbb, unsigned short id, bool return_deleted, bool noscan, unsigned short flags) Line 7975 at C:\firebird-build\gen\jrd\met.cpp(7975) engine13.dll!Jrd::ProcedureSourceNode::parse(Jrd::thread_db * tdbb, Jrd::CompilerScratch * csb, const short blrOp, bool parseContext) Line 1041 at C:\firebird-build\src\jrd\RecordSourceNodes.cpp(1041) engine13.dll!PAR_parseRecordSource(Jrd::thread_db * tdbb, Jrd::CompilerScratch * csb) Line 1284 at C:\firebird-build\src\jrd\par.cpp(1284) engine13.dll!PAR_rse(Jrd::thread_db * tdbb, Jrd::CompilerScratch * csb, short rse_op) Line 1333 at C:\firebird-build\src\jrd\par.cpp(1333) engine13.dll!PAR_rse(Jrd::thread_db * tdbb, Jrd::CompilerScratch * csb) Line 1465 at C:\firebird-build\src\jrd\par.cpp(1465) engine13.dll!Jrd::ForNode::parse(Jrd::thread_db * tdbb, Firebird::MemoryPool & pool, Jrd::CompilerScratch * csb, const unsigned char blrOp) Line 4991 at C:\firebird-build\src\dsql\StmtNodes.cpp(4991) engine13.dll!PAR_parse_node(Jrd::thread_db * tdbb, Jrd::CompilerScratch * csb) Line 1650 at C:\firebird-build\src\jrd\par.cpp(1650) engine13.dll!PAR_parse_stmt(Jrd::thread_db * tdbb, Jrd::CompilerScratch * csb) Line 1592 at C:\firebird-build\src\jrd\par.cpp(1592) engine13.dll!Jrd::ReceiveNode::parse(Jrd::thread_db * tdbb, Firebird::MemoryPool & pool, Jrd::CompilerScratch * csb, const unsigned char blrOp) Line 7481 at C:\firebird-build\src\dsql\StmtNodes.cpp(7481) engine13.dll!PAR_parse_node(Jrd::thread_db * tdbb, Jrd::CompilerScratch * csb) Line 1650 at C:\firebird-build\src\jrd\par.cpp(1650) engine13.dll!PAR_parse_stmt(Jrd::thread_db * tdbb, Jrd::CompilerScratch * csb) Line 1592 at C:\firebird-build\src\jrd\par.cpp(1592) engine13.dll!Jrd::CompoundStmtNode::parse(Jrd::thread_db * tdbb, Firebird::MemoryPool & pool, Jrd::CompilerScratch * csb, const unsigned char __formal) Line 790 at C:\firebird-build\src\dsql\StmtNodes.cpp(790) engine13.dll!PAR_parse_node(Jrd::thread_db * tdbb, Jrd::CompilerScratch * csb) Line 1650 at C:\firebird-build\src\jrd\par.cpp(1650) engine13.dll!PAR_parse(Jrd::thread_db * tdbb, const unsigned char * blr, unsigned long blr_length, bool internal_flag, unsigned long dbginfo_length, const unsigned char * dbginfo) Line 701 at C:\firebird-build\src\jrd\par.cpp(701) engine13.dll!CMP_compile(Jrd::thread_db * tdbb, const unsigned char * blr, unsigned long blrLength, bool internalFlag, unsigned long dbginfoLength, const unsigned char * dbginfo) Line 161 at C:\firebird-build\src\jrd\cmp.cpp(161) engine13.dll!Jrd::DsqlDmlStatement::dsqlPass(Jrd::thread_db * tdbb, Jrd::DsqlCompilerScratch * scratch, unsigned int * traceResult) Line 193 at C:\firebird-build\src\dsql\DsqlStatements.cpp(193) engine13.dll!prepareStatement(Jrd::thread_db * tdbb, Jrd::dsql_dbb * database, Jrd::jrd_tra * transaction, unsigned long textLength, const char * text, unsigned short clientDialect, bool isInternalRequest, unsigned int * traceResult) Line 615 at C:\firebird-build\src\dsql\dsql.cpp(615) engine13.dll!prepareRequest(Jrd::thread_db * tdbb, Jrd::dsql_dbb * database, Jrd::jrd_tra * transaction, unsigned long textLength, const char * text, unsigned short clientDialect, bool isInternalRequest) Line 453 at C:\firebird-build\src\dsql\dsql.cpp(453) engine13.dll!DSQL_prepare(Jrd::thread_db * tdbb, Jrd::Attachment * attachment, Jrd::jrd_tra * transaction, unsigned long length, const char * string, unsigned short dialect, unsigned int prepareFlags, Firebird::Array<unsigned char,Firebird::EmptyStorage> * items, Firebird::Array<unsigned char,Firebird::EmptyStorage> * buffer, bool isInternalRequest) Line 263 at C:\firebird-build\src\dsql\dsql.cpp(263) engine13.dll!Jrd::JAttachment::prepare(Firebird::CheckStatusWrapper * user_status, Firebird::ITransaction * apiTra, unsigned int stmtLength, const char * sqlStmt, unsigned int dialect, unsigned int flags) Line 5650 at C:\firebird-build\src\jrd\jrd.cpp(5650) engine13.dll!Firebird::IAttachmentBaseImpl<Jrd::JAttachment,Firebird::CheckStatusWrapper,Firebird::IReferenceCountedImpl<Jrd::JAttachment,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IVersionedImpl<Jrd::JAttachment,Firebird::CheckStatusWrapper,Firebird::InheritFirebird::IAttachment>>>>::cloopprepareDispatcher(Firebird::IAttachment * self, Firebird::IStatus * status, Firebird::ITransaction * tra, unsigned int stmtLength, const char * sqlStmt, unsigned int dialect, unsigned int flags) Line 11761 at C:\firebird-build\src\include\firebird\IdlFbInterfaces.h(11761) [Inline Frame] fbclient.dll!Firebird::IAttachment::prepare(Firebird::CheckStatusWrapper *) Line 2628 at C:\firebird-build\src\include\firebird\IdlFbInterfaces.h(2628) fbclient.dll!Why::YAttachment::prepare(Firebird::CheckStatusWrapper * status, Firebird::ITransaction * transaction, unsigned int stmtLength, const char * sqlStmt, unsigned int dialect, unsigned int flags) Line 5618 at C:\firebird-build\src\yvalve\why.cpp(5618) fbclient.dll!isc_dsql_prepare(int * userStatus, void * * traHandle, void * * stmtHandle, unsigned short stmtLength, const char * sqlStmt, unsigned short dialect, XSQLDA * sqlda) Line 2688 at C:\firebird-build\src\yvalve\why.cpp(2688) [Managed to Native Transition] FB_1182347569_Assembly!FB_1182347569_Class.FirebirdSql.Data.Client.Native.IFbClient.isc_dsql_prepare(nint[] statusVector, ref FirebirdSql.Data.Client.Native.Handle.TransactionHandle trHandle, ref FirebirdSql.Data.Client.Native.Handle.StatementHandle stmtHandle, short length, byte[] statement, short dialect, nint xsqlda) FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Client.Native.FesStatement.Prepare(string commandText) Line 231 at FirebirdSql.Data.Client.Native\FesStatement.cs(231) FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.FirebirdClient.FbCommand.Prepare(bool returnsSet) Line 1394 at FirebirdSql.Data.FirebirdClient\FbCommand.cs(1394) FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteCommand(System.Data.CommandBehavior behavior, bool returnsSet) Line 1451 at FirebirdSql.Data.FirebirdClient\FbCommand.cs(1451) FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteReader(System.Data.CommandBehavior behavior) Line 563 at FirebirdSql.Data.FirebirdClient\FbCommand.cs(563) FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteDbDataReader(System.Data.CommandBehavior behavior) Line 730 at FirebirdSql.Data.FirebirdClient\FbCommand.cs(730) System.Data.Common.dll!System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(System.Data.CommandBehavior behavior) Line 145 at System.Data.Common\DbCommand.cs(145) DatabaseAccess.dll!DatabaseAccess.FireBird.FireBirdDatabase.DoExecuteReader(System.Data.IDbCommand command, System.Data.CommandBehavior cmdBehavior) Line 147 at DatabaseAccess.FireBird\FireBirdDatabase.cs(147)

nir-moshe avatar Oct 27 '25 13:10 nir-moshe

Usually, before writing about a problem in the tracker, you should try updating Firebird to the latest version in the current version, that is, to 5.0.3, and try to reproduce the problem there.

An unrelated question. Why are you using Charset=UNICODE_FSS instead of Charset=UTF8?

sim1984 avatar Oct 27 '25 14:10 sim1984

Multiple hangs and crashes where fixed in 5.0.2 and 5.0.3. I can't tell from their descriptions if one of them matches yours. Please verify if upgrading to 5.0.3 fixes it.

mrotteveel avatar Oct 28 '25 07:10 mrotteveel

Thanks, I tried to update to 5.0.3 and I experience the same issue. Now I have a different example of a thread hanging while setting the UpdateCommand when creating a new DbDataAdapter.

what can cause this?

about Charset=UNICODE_FSS, I will try to change it to UTF8, not sure the reason I used it.

stackTrace is: ntdll.dll!_NtWaitForAlertByThreadId@8() Unknown ntdll.dll!@RtlpWaitOnAddressWithTimeout@20() Unknown ntdll.dll!_RtlpWaitOnCriticalSection@8() Unknown ntdll.dll!_RtlpEnterCriticalSectionContended@8() Unknown ntdll.dll!_RtlEnterCriticalSection@4() Unknown [Inline Frame] engine13.dll!Firebird::Mutex::enter(const char *) Line 94 C++ engine13.dll!Jrd::AttachmentHolder::AttachmentHolder(Jrd::thread_db * tdbb, Jrd::StableAttachmentPart * sa, unsigned int lockFlags, const char * from) Line 795 C++ engine13.dll!Jrd::EngineContextHolder::EngineContextHolderJrd::JTransaction(Firebird::CheckStatusWrapper * status, Jrd::JTransaction * interfacePtr, const char * from, unsigned int lockFlags) Line 866 C++ engine13.dll!Jrd::JTransaction::internalRollback(Firebird::CheckStatusWrapper * user_status) Line 4153 C++ [Inline Frame] engine13.dll!Jrd::JTransaction::rollback(Firebird::CheckStatusWrapper *) Line 4126 C++ engine13.dll!Firebird::ITransactionBaseImpl<Jrd::JTransaction,Firebird::CheckStatusWrapper,Firebird::IReferenceCountedImpl<Jrd::JTransaction,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IVersionedImpl<Jrd::JTransaction,Firebird::CheckStatusWrapper,Firebird::InheritFirebird::ITransaction>>>>::clooprollbackDispatcher(Firebird::ITransaction * self, Firebird::IStatus * status) Line 9615 C++ [Inline Frame] fbclient.dll!Firebird::ITransaction::rollback(Firebird::CheckStatusWrapper *) Line 1345 C++ [Inline Frame] fbclient.dll!Why::YTransaction::rollback::__l3::<lambda_ebbbb4a8a12fa42f99214f5025f947fa>::operator()() Line 5403 C++ [Inline Frame] fbclient.dll!std::invoke(Why::YTransaction::rollback::__l3::<lambda_ebbbb4a8a12fa42f99214f5025f947fa> &) Line 1752 C++ fbclient.dll!std::_Func_impl_no_alloc<<lambda_ebbbb4a8a12fa42f99214f5025f947fa>,void>::_Do_call() Line 839 C++ [Inline Frame] fbclient.dll!std::_Func_class::operator()() Line 883 C++ fbclient.dll!Why::doneWhy::YTransaction(Firebird::CheckStatusWrapper * status, Why::YEntryWhy::YTransaction & entry, Why::YTransaction * y, std::function<void __cdecl(void)> newClose, std::function<void __cdecl(void)> oldClose) Line 1356 C++ fbclient.dll!Why::YTransaction::rollback(Firebird::CheckStatusWrapper * status) Line 5402 C++ fbclient.dll!isc_rollback_transaction(int * userStatus, void * * traHandle) Line 3355 C++ [Managed to Native Transition] FB_205378979_Assembly!FB_205378979_Class.FirebirdSql.Data.Client.Native.IFbClient.isc_rollback_transaction(System.IntPtr[] statusVector, ref FirebirdSql.Data.Client.Native.Handles.TransactionHandle trHandle) Unknown FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Client.Native.FesTransaction.Rollback() Line 186 C# FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.FirebirdClient.FbTransaction.Rollback() Line 118 C# FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.FirebirdClient.FbCommand.RollbackImplicitTransaction() Line 920 C# FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.FirebirdClient.FbCommand.Release() Line 995 C# FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.FirebirdClient.FbCommand.Connection.set(FirebirdSql.Data.FirebirdClient.FbConnection value) Line 129 C# FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.FirebirdClient.FbCommand.DbConnection.set(System.Data.Common.DbConnection value) Line 227 C# System.Data.dll!System.Data.Common.DbCommand.System.Data.IDbCommand.Connection.set(System.Data.IDbConnection value) Unknown

ScanTypes.dll!ScanTypes.Repository.BatchAccessor.CreateAdapter(System.Data.IDbConnection connection) Line 493 C#

nir-moshe avatar Oct 29 '25 07:10 nir-moshe

Provide a full memory dump's of all processes that have connections to the database

hvlad avatar Nov 03 '25 15:11 hvlad

Anything ?

hvlad avatar Nov 14 '25 12:11 hvlad