FirebirdSQL / firebird

Firebird server, client and tools
https://www.firebirdsql.org/
1.19k stars 204 forks source link

The server crashes on DB connection if previously it crashed just after creating a new TIP and advancing NT in the header #8064

Closed ilya071294 closed 1 month ago

ilya071294 commented 1 month ago

Seems like only master branch is affected. The stack trace on the debug build (on the release it's basically the same):

>   engine13.dll!fb_assert_impl(const char * msg, const char * file, int line, bool do_abort) Строка 48 C++
    engine13.dll!Jrd::TipCache::generateStatementId() Строка 1150   C++
    engine13.dll!Jrd::Database::generateStatementId() Строка 89 C++
    engine13.dll!Jrd::Statement::getStatementId() Строка 65 C++
    engine13.dll!EXE_start(Jrd::thread_db * tdbb, Jrd::Request * request, Jrd::jrd_tra * transaction) Строка 878    C++
    engine13.dll!DPM_scan_pages(Jrd::thread_db * tdbb) Строка 2219  C++
    engine13.dll!inventory_page(Jrd::thread_db * tdbb, unsigned long sequence) Строка 2385  C++
    engine13.dll!TRA_get_inventory(Jrd::thread_db * tdbb, unsigned char * bit_vector, unsigned __int64 base, unsigned __int64 top) Строка 700   C++
    engine13.dll!Jrd::TipCache::loadInventoryPages(Jrd::thread_db * tdbb, Jrd::TipCache::GlobalTpcHeader * header) Строка 331   C++
    engine13.dll!Jrd::TipCache::GlobalTpcInitializer::initialize(Firebird::SharedMemoryBase * sm, bool initFlag) Строка 78  C++
    engine13.dll!Firebird::SharedMemoryBase::SharedMemoryBase(const char * filename, unsigned long length, Firebird::IpcObject * cb, bool __formal) Строка 1972 C++
    engine13.dll!Firebird::SharedMemory<Jrd::TipCache::GlobalTpcHeader>::SharedMemory<Jrd::TipCache::GlobalTpcHeader>(const char * fileName, unsigned long size, Firebird::IpcObject * cb, bool skipLock) Строка 352    C++
    engine13.dll!Jrd::TipCache::initializeTpc(Jrd::thread_db * tdbb) Строка 249 C++
    engine13.dll!Jrd::JProvider::internalAttach(Firebird::CheckStatusWrapper * user_status, const char * const filename, unsigned int dpb_length, const unsigned char * dpb, const Jrd::UserId * existingId) Строка 1845    C++
    engine13.dll!Jrd::JProvider::attachDatabase(Firebird::CheckStatusWrapper * user_status, const char * filename, unsigned int dpb_length, const unsigned char * dpb) Строка 1607  C++
    engine13.dll!Firebird::IProviderBaseImpl<Jrd::JProvider,Firebird::CheckStatusWrapper,Firebird::IPluginBaseImpl<Jrd::JProvider,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IReferenceCountedImpl<Jrd::JProvider,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IVersionedImpl<Jrd::JProvider,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IProvider>>>>>>>::cloopattachDatabaseDispatcher(Firebird::IProvider * self, Firebird::IStatus * status, const char * fileName, unsigned int dpbLength, const unsigned char * dpb) Строка 12230  C++
    fbclient.dll!Firebird::IProvider::attachDatabase<Firebird::CheckStatusWrapper>(Firebird::CheckStatusWrapper * status, const char * fileName, unsigned int dpbLength, const unsigned char * dpb) Строка 2914 C++
    fbclient.dll!Why::Dispatcher::attachOrCreateDatabase(Firebird::CheckStatusWrapper * status, bool createFlag, const char * filename, unsigned int dpbLength, const unsigned char * dpb) Строка 6463  C++
    fbclient.dll!Why::Dispatcher::attachDatabase(Firebird::CheckStatusWrapper * status, const char * filename, unsigned int dpbLength, const unsigned char * dpb) Строка 6377   C++
    fbclient.dll!Firebird::IProviderBaseImpl<Why::Dispatcher,Firebird::CheckStatusWrapper,Firebird::IPluginBaseImpl<Why::Dispatcher,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IReferenceCountedImpl<Why::Dispatcher,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IVersionedImpl<Why::Dispatcher,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IProvider>>>>>>>::cloopattachDatabaseDispatcher(Firebird::IProvider * self, Firebird::IStatus * status, const char * fileName, unsigned int dpbLength, const unsigned char * dpb) Строка 12230  C++
    firebird.exe!Firebird::IProvider::attachDatabase<Firebird::CheckStatusWrapper>(Firebird::CheckStatusWrapper * status, const char * fileName, unsigned int dpbLength, const unsigned char * dpb) Строка 2914 C++
    firebird.exe!`anonymous namespace'::DatabaseAuth::accept(packet * send, Auth::WriterImplementation * authBlock) Строка 2501 C++
    firebird.exe!`anonymous namespace'::ServerAuth::authenticate(packet * send, unsigned int flags) Строка 597  C++
    firebird.exe!attach_database(rem_port * port, P_OP operation, p_atch * attach, packet * send) Строка 2440   C++
    firebird.exe!process_packet(rem_port * port, packet * sendL, packet * receive, rem_port * * result) Строка 4983 C++
    firebird.exe!loopThread(void * __formal) Строка 6717    C++
    firebird.exe!`anonymous namespace'::ThreadArgs::run() Строка 78 C++
    firebird.exe!threadStart(void * arg) Строка 97  C++

The database for reproducing the issue: EMPLOYEE_FB_MASTER.zip

The last created TIP has not been added to RDB$PAGES, and this is why DPM_scan_pages was called. But it's not a problem because inventory_page is able to reconstruct the TIP chain using tip_next.

AlexPeshkoff commented 1 month ago

On 4/2/24 16:01, Ilya Eremin wrote:

Seems like only |master| branch is affected. The stack trace on the debug build (on the release it's basically the same):

|1> engine13.dll!fb_assert_impl(const char msg, const char file, int line, bool do_abort) Строка 48 C++ engine13.dll!Jrd::TipCache::generateStatementId() Строка 1150 C++|

Got it. I've used to fix more or less same bug a few weeks ago, will fix this too.

|engine13.dll!Jrd::Database::generateStatementId() Строка 89 C++ engine13.dll!Jrd::Statement::getStatementId() Строка 65 C++ engine13.dll!EXE_start(Jrd::thread_db tdbb, Jrd::Request request, Jrd::jrd_tra transaction) Строка 878 C++ engine13.dll!DPM_scan_pages(Jrd::thread_db tdbb) Строка 2219 C++ engine13.dll!inventory_page(Jrd::thread_db tdbb, unsigned long sequence) Строка 2385 C++ engine13.dll!TRA_get_inventory(Jrd::thread_db tdbb, unsigned char bit_vector, unsigned int64 base, unsigned int64 top) Строка 700 C++ engine13.dll!Jrd::TipCache::loadInventoryPages(Jrd::thread_db tdbb, Jrd::TipCache::GlobalTpcHeader * header) Строка 331 C++ engine13.dll!Jrd::TipCache::GlobalTpcInitializer::initialize(Firebird::SharedMemoryBase

  • sm, bool initFlag) Строка 78 C++ engine13.dll!Firebird::SharedMemoryBase::SharedMemoryBase(const char filename, unsigned long length, Firebird::IpcObject cb, bool __formal) Строка 1972 C++ engine13.dll!Firebird::SharedMemory::SharedMemory(const char fileName, unsigned long size, Firebird::IpcObject cb, bool skipLock) Строка 352 C++ engine13.dll!Jrd::TipCache::initializeTpc(Jrd::thread_db * tdbb) Строка 249 C++ engine13.dll!Jrd::JProvider::internalAttach(Firebird::CheckStatusWrapper
  • user_status, const char const filename, unsigned int dpb_length, const unsigned char dpb, const Jrd::UserId * existingId) Строка 1845 C++ engine13.dll!Jrd::JProvider::attachDatabase(Firebird::CheckStatusWrapper
  • user_status, const char filename, unsigned int dpb_length, const unsigned char dpb) Строка 1607 C++ engine13.dll!Firebird::IProviderBaseImpl<Jrd::JProvider,Firebird::CheckStatusWrapper,Firebird::IPluginBaseImpl<Jrd::JProvider,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IReferenceCountedImpl<Jrd::JProvider,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IVersionedImpl<Jrd::JProvider,Firebird::CheckStatusWrapper,Firebird::Inherit>>>>>>::cloopattachDatabaseDispatcher(Firebird::IProvider
  • self, Firebird::IStatus status, const char fileName, unsigned int dpbLength, const unsigned char * dpb) Строка 12230 C++ fbclient.dll!Firebird::IProvider::attachDatabase(Firebird::CheckStatusWrapper
  • status, const char fileName, unsigned int dpbLength, const unsigned char dpb) Строка 2914 C++ fbclient.dll!Why::Dispatcher::attachOrCreateDatabase(Firebird::CheckStatusWrapper
  • status, bool createFlag, const char filename, unsigned int dpbLength, const unsigned char dpb) Строка 6463 C++ fbclient.dll!Why::Dispatcher::attachDatabase(Firebird::CheckStatusWrapper
  • status, const char filename, unsigned int dpbLength, const unsigned char dpb) Строка 6377 C++ fbclient.dll!Firebird::IProviderBaseImpl<Why::Dispatcher,Firebird::CheckStatusWrapper,Firebird::IPluginBaseImpl<Why::Dispatcher,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IReferenceCountedImpl<Why::Dispatcher,Firebird::CheckStatusWrapper,Firebird::Inherit<Firebird::IVersionedImpl<Why::Dispatcher,Firebird::CheckStatusWrapper,Firebird::Inherit>>>>>>::cloopattachDatabaseDispatcher(Firebird::IProvider
  • self, Firebird::IStatus status, const char fileName, unsigned int dpbLength, const unsigned char * dpb) Строка 12230 C++ firebird.exe!Firebird::IProvider::attachDatabase(Firebird::CheckStatusWrapper
  • status, const char fileName, unsigned int dpbLength, const unsigned char dpb) Строка 2914 C++ firebird.exe!anonymous namespace'::DatabaseAuth::accept(packet * send, Auth::WriterImplementation * authBlock) Строка 2501 C++ firebird.exe!anonymous namespace'::ServerAuth::authenticate(packet send, unsigned int flags) Строка 597 C++ firebird.exe!attach_database(rem_port port, P_OP operation, p_atch attach, packet send) Строка 2440 C++ firebird.exe!process_packet(rem_port port, packet sendL, packet receive, rem_port result) Строка 4983 C++ firebird.exe!loopThread(void __formal) Строка 6717 C++ firebird.exe!`anonymous namespace'::ThreadArgs::run() Строка 78 C++ firebird.exe!threadStart(void * arg) Строка 97 C++ |

The database for reproducing the issue: EMPLOYEE_FB_MASTER.zip https://github.com/FirebirdSQL/firebird/files/14836807/EMPLOYEE_FB_MASTER.zip

The last created TIP has not been added to |RDB$PAGES|, and this is why |DPM_scan_pages| was called. But it's not a problem because |inventory_page| is able to reconstruct the TIP chain using |tip_next|.

— Reply to this email directly, view it on GitHub https://github.com/FirebirdSQL/firebird/issues/8064, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA44OUNVBTGERV6A4J3X37LY3KTZNAVCNFSM6AAAAABFTLE6UOVHI2DSMVQWIX3LMV43ASLTON2WKOZSGIZDANBWHAYDMMA. You are receiving this because you are subscribed to this thread.Message ID: @.***>

dyemanov commented 1 month ago

I don't see how it could happen in master. initializeTpc() is called before dbb_tip_cache is assigned and Database::generateStatementId() has a protection check, so it should return 0.

ilya071294 commented 1 month ago

I don't see how it could happen in master. initializeTpc() is called before dbb_tip_cache is assigned and Database::generateStatementId() has a protection check, so it should return 0.

Yes, looks like it's already fixed by 987d6ac1e3c96c140e2a6774f70a1696abcc65f0. My local branch was a bit older. I'm closing the issue then.