From 71b0968070ba18cb59f285f3e0c007e935599d59 Mon Sep 17 00:00:00 2001 From: Yuhong Zhang Date: Mon, 28 Mar 2022 13:20:31 +0000 Subject: SERVER-55173 Skip releasing cursors during shutdown to avoid segmentation fault (cherry picked from commit bc940d6b0adc9254b62e9daf9c92d2c92f8b083d) --- .../db/storage/wiredtiger/wiredtiger_session_cache.cpp | 8 +++++++- .../storage/wiredtiger/wiredtiger_session_cache_test.cpp | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp index a627dd65d5b..dec3ca6a29e 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp @@ -135,6 +135,11 @@ WT_CURSOR* WiredTigerSession::getNewCursor(const std::string& uri, const char* c } void WiredTigerSession::releaseCursor(uint64_t id, WT_CURSOR* cursor, const std::string& config) { + // Avoids the cursor already being destroyed during the shutdown. + if (_cache->isShuttingDown()) { + return; + } + invariant(_session); invariant(cursor); _cursorsOut--; @@ -473,7 +478,8 @@ UniqueWiredTigerSession WiredTigerSessionCache::getSession() { void WiredTigerSessionCache::releaseSession(WiredTigerSession* session) { invariant(session); - invariant(session->cursorsOut() == 0); + // We might have skipped releasing some cursors during the shutdown. + invariant(session->cursorsOut() == 0 || isShuttingDown()); const int shuttingDown = _shuttingDown.fetchAndAdd(1); ON_BLOCK_EXIT([this] { _shuttingDown.fetchAndSubtract(1); }); diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache_test.cpp index a894d189afb..a71110a7cdd 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache_test.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache_test.cpp @@ -114,4 +114,19 @@ TEST(WiredTigerSessionCacheTest, CheckSessionCacheCleanup) { ASSERT_EQUALS(sessionCache->getIdleSessionsCount(), 0U); } +TEST(WiredTigerSessionCacheTest, ReleaseCursorDuringShutdown) { + WiredTigerSessionCacheHarnessHelper harnessHelper(""); + WiredTigerSessionCache* sessionCache = harnessHelper.getSessionCache(); + UniqueWiredTigerSession session = sessionCache->getSession(); + // Simulates the cursor already being deleted during shutdown. + WT_CURSOR* cursor = nullptr; + + sessionCache->shuttingDown(); + ASSERT(sessionCache->isShuttingDown()); + + auto tableIdWeDontCareAbout = WiredTigerSession::genTableId(); + // Skips actually trying to release the cursor to avoid the segmentation fault. + session->releaseCursor(tableIdWeDontCareAbout, cursor, ""); +} + } // namespace mongo -- cgit v1.2.1