Thread hang when multiple Windows 11 processes write concurrently to same embedded Firebird 5.0.1 DB
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
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?
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.
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
ScanTypes.dll!ScanTypes.Repository.BatchAccessor.CreateAdapter(System.Data.IDbConnection connection) Line 493 C#
Provide a full memory dump's of all processes that have connections to the database
Anything ?