From e1e52ec682834fe40387a7794b7d3fd9165327c8 Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Fri, 19 Dec 2025 21:00:09 +0800 Subject: [PATCH 01/15] Increase coroutine stack size to 8MB --- src/mongo/db/kill_sessions_local.cpp | 4 +++- src/mongo/transport/service_state_machine.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mongo/db/kill_sessions_local.cpp b/src/mongo/db/kill_sessions_local.cpp index 8419f61b5e..e2cafce6c0 100644 --- a/src/mongo/db/kill_sessions_local.cpp +++ b/src/mongo/db/kill_sessions_local.cpp @@ -74,7 +74,9 @@ SessionKiller::Result killSessionsLocal(OperationContext* opCtx, } struct CoroCtx { - static constexpr size_t kCoroStackSize = 3200 * 1024; + // Coroutine stack size: Increased from 3.2MB to 8MB to prevent stack overflow + // in complex database operations (deep recursion, large BSON processing, etc.) + static constexpr size_t kCoroStackSize = 8192 * 1024; // 8MB boost::context::protected_fixedsize_stack salloc{kCoroStackSize}; boost::context::continuation source; std::function resumeTask; diff --git a/src/mongo/transport/service_state_machine.h b/src/mongo/transport/service_state_machine.h index e68db8f705..9f10205387 100644 --- a/src/mongo/transport/service_state_machine.h +++ b/src/mongo/transport/service_state_machine.h @@ -282,7 +282,9 @@ class ServiceStateMachine : public std::enable_shared_from_this Date: Sat, 20 Dec 2025 09:12:45 +0800 Subject: [PATCH 02/15] Fix unaligned stack pointer can cause crashes in jump_fcontext() --- src/mongo/transport/service_state_machine.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mongo/transport/service_state_machine.cpp b/src/mongo/transport/service_state_machine.cpp index aa9cbb04b9..c2d7858a96 100644 --- a/src/mongo/transport/service_state_machine.cpp +++ b/src/mongo/transport/service_state_machine.cpp @@ -55,6 +55,7 @@ #include #include +#include #include #include #include @@ -734,8 +735,11 @@ void ServiceStateMachine::setThreadGroupId(size_t id) { boost::context::stack_context ServiceStateMachine::_coroStackContext() { boost::context::stack_context sc; sc.size = kCoroStackSize - _osPageSize; - // Because stack grows downwards from high address? - sc.sp = _coroStack + kCoroStackSize; + // Stack grows downwards from high address. Align stack pointer to 16-byte boundary + // (required for x86-64 ABI and SIMD instructions) + char* top = _coroStack + kCoroStackSize; + // Align down to 16-byte boundary + sc.sp = reinterpret_cast(reinterpret_cast(top) & ~static_cast(15)); return sc; } From aed3ee055f1d100035cfeaaef64a3a777a6e3924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E6=99=93=E9=98=B3?= Date: Sat, 20 Dec 2025 11:25:39 +0800 Subject: [PATCH 03/15] Debug jump_fcontext crash --- src/mongo/db/kill_sessions_local.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mongo/db/kill_sessions_local.cpp b/src/mongo/db/kill_sessions_local.cpp index e2cafce6c0..a739d35413 100644 --- a/src/mongo/db/kill_sessions_local.cpp +++ b/src/mongo/db/kill_sessions_local.cpp @@ -113,7 +113,7 @@ void killAllExpiredTransactions(OperationContext* opCtx) { getGlobalServiceContext()->getServiceEntryPoint()->getServiceExecutor(); coroCtx->resumeTask = [&source = coroCtx->source, &client] { - log() << "abortArbitraryTransactionIfExpired call resume."; + error() << "abortArbitraryTransactionIfExpired call resume."; Client::setCurrent(std::move(client)); source = source.resume(); }; @@ -131,7 +131,7 @@ void killAllExpiredTransactions(OperationContext* opCtx) { [&finished, &mux, &cv, coroCtx, opCtx, session, &client, serviceExecutor]( boost::context::continuation&& sink) { coroCtx->yieldFunc = [&sink, &client]() { - log() << "abortArbitraryTransactionIfExpired call yield."; + error() << "abortArbitraryTransactionIfExpired call yield."; client = Client::releaseCurrent(); sink = sink.resume(); }; From 60eba8cb68621eabf76f84a1cf486e5082c7990f Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Sat, 20 Dec 2025 13:49:02 +0800 Subject: [PATCH 04/15] fix the sp.size alignment as well --- src/mongo/transport/service_state_machine.cpp | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/mongo/transport/service_state_machine.cpp b/src/mongo/transport/service_state_machine.cpp index c2d7858a96..926887ee53 100644 --- a/src/mongo/transport/service_state_machine.cpp +++ b/src/mongo/transport/service_state_machine.cpp @@ -734,12 +734,26 @@ void ServiceStateMachine::setThreadGroupId(size_t id) { boost::context::stack_context ServiceStateMachine::_coroStackContext() { boost::context::stack_context sc; - sc.size = kCoroStackSize - _osPageSize; - // Stack grows downwards from high address. Align stack pointer to 16-byte boundary - // (required for x86-64 ABI and SIMD instructions) + // Stack grows downwards from high address. + // + // We reserve the first OS page as a guard page (PROT_NONE), so the usable region is: + // [bottom, top) + // where: + // bottom = _coroStack + _osPageSize + // top = _coroStack + kCoroStackSize + // + // Boost.Context models the usable range as [sp - size, sp), so if we align sp down we must + // also recompute size from the aligned sp to keep the bottom boundary correct. + char* bottom = _coroStack + _osPageSize; char* top = _coroStack + kCoroStackSize; - // Align down to 16-byte boundary - sc.sp = reinterpret_cast(reinterpret_cast(top) & ~static_cast(15)); + + // Align down to 16-byte boundary (common ABI requirement on x86-64 and for SIMD). + char* sp = + reinterpret_cast(reinterpret_cast(top) & ~static_cast(15)); + + invariant(sp > bottom); + sc.sp = sp; + sc.size = static_cast(sp - bottom); return sc; } From c994e742fb53059c6bb87569d95c205d66455f7c Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Sat, 20 Dec 2025 14:13:41 +0800 Subject: [PATCH 05/15] update submodule --- src/mongo/db/modules/eloq/data_substrate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mongo/db/modules/eloq/data_substrate b/src/mongo/db/modules/eloq/data_substrate index 01b3961541..8c9314aa4e 160000 --- a/src/mongo/db/modules/eloq/data_substrate +++ b/src/mongo/db/modules/eloq/data_substrate @@ -1 +1 @@ -Subproject commit 01b396154133a25f7a49f6546d40bb7148cf2df6 +Subproject commit 8c9314aa4edb6e70a47761cc27c93a7ad4f8551b From dcc754766d5a2cd05b1153ef62ebb94869b77827 Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Sat, 20 Dec 2025 22:47:45 +0800 Subject: [PATCH 06/15] Fix dangling reference in coroutine resume functors ServiceExecutorCoroutine::coroutineResumeFunctor() and coroutineLongResumeFunctor() captured the task parameter by reference, leaving lambdas with a dangling reference after the function returned. Under load this could corrupt memory and crash later (e.g. in munmap). Capture Task by value (copy) inside the returned functors to ensure correct lifetime. --- src/mongo/transport/service_executor_coroutine.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/mongo/transport/service_executor_coroutine.cpp b/src/mongo/transport/service_executor_coroutine.cpp index 3be9c3c7a7..69db5501c6 100644 --- a/src/mongo/transport/service_executor_coroutine.cpp +++ b/src/mongo/transport/service_executor_coroutine.cpp @@ -316,13 +316,22 @@ Status ServiceExecutorCoroutine::schedule(Task task, std::function ServiceExecutorCoroutine::coroutineResumeFunctor(uint16_t threadGroupId, const Task& task) { invariant(threadGroupId < _threadGroups.size()); - return [thd_group = &_threadGroups[threadGroupId], &task]() { thd_group->resumeTask(task); }; + // IMPORTANT: capture task by value. Capturing by reference here would dangle because `task` + // is a reference to this function's parameter, which goes out of scope when we return. + Task taskCopy = task; + return [thd_group = &_threadGroups[threadGroupId], task = std::move(taskCopy)]() mutable { + thd_group->resumeTask(task); + }; } std::function ServiceExecutorCoroutine::coroutineLongResumeFunctor(uint16_t threadGroupId, const Task& task) { invariant(threadGroupId < _threadGroups.size()); - return [thd_group = &_threadGroups[threadGroupId], &task]() { thd_group->enqueueTask(task); }; + // Same lifetime rule as coroutineResumeFunctor(): capture by value to avoid dangling refs. + Task taskCopy = task; + return [thd_group = &_threadGroups[threadGroupId], task = std::move(taskCopy)]() mutable { + thd_group->enqueueTask(task); + }; } void ServiceExecutorCoroutine::ongoingCoroutineCountUpdate(uint16_t threadGroupId, int delta) { From d675efa3df558f177ee1c76c2943db55664d6b65 Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Sun, 21 Dec 2025 08:37:17 +0800 Subject: [PATCH 07/15] Harden coroutine functors against SSM teardown races Fix potential use-after-free during coroutine resume/yield by avoiding raw this captures in queued resume tasks. Use weak_from_this() for _resumeTask and thread-group migration functor so queued callbacks become no-ops after ServiceStateMachine destruction. Additionally, disable Client coroutine functors and clear SSM coroutine callbacks in _cleanupSession() to prevent yield/resume calls racing with coroutine stack teardown. --- src/mongo/transport/service_state_machine.cpp | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/mongo/transport/service_state_machine.cpp b/src/mongo/transport/service_state_machine.cpp index 926887ee53..63b3ec4f19 100644 --- a/src/mongo/transport/service_state_machine.cpp +++ b/src/mongo/transport/service_state_machine.cpp @@ -544,7 +544,15 @@ void ServiceStateMachine::_runNextInGuard(ThreadGuard guard) { _coroStatus = CoroStatus::OnGoing; _serviceExecutor->ongoingCoroutineCountUpdate( _threadGroupId.load(std::memory_order_relaxed), 1); - _resumeTask = [ssm = this] { + // IMPORTANT: resume tasks can be queued and executed asynchronously. + // Avoid capturing a raw `this` pointer to prevent UAF during shutdown. + auto wssm = weak_from_this(); + _resumeTask = [wssm] { + auto ssm = wssm.lock(); + if (!ssm) { + return; + } + Client::setCurrent(std::move(ssm->_dbClient)); if (ssm->_migrating.load(std::memory_order_relaxed)) { ssm->_coroResume(); @@ -566,8 +574,11 @@ void ServiceStateMachine::_runNextInGuard(ThreadGuard guard) { _threadGroupId.load(std::memory_order_relaxed), _resumeTask); _coroLongResume = _serviceExecutor->coroutineLongResumeFunctor( _threadGroupId.load(std::memory_order_relaxed), _resumeTask); - _coroMigrateThreadGroup = std::bind( - &ServiceStateMachine::_migrateThreadGroup, this, std::placeholders::_1); + _coroMigrateThreadGroup = [wssm](uint16_t threadGroupId) { + if (auto ssm = wssm.lock()) { + ssm->_migrateThreadGroup(threadGroupId); + } + }; boost::context::stack_context sc = _coroStackContext(); boost::context::preallocated prealloc(sc.sp, sc.size, sc); @@ -580,9 +591,17 @@ void ServiceStateMachine::_runNextInGuard(ThreadGuard guard) { if (!ssm) { return std::move(sink); } - ssm->_coroYield = [ssm = ssm.get(), &sink]() { + // IMPORTANT: Store a yield functor that won't UAF if invoked + // during teardown. If SSM is gone, we still resume `sink` to + // avoid deadlocks/spins in coro::Mutex/ConditionVariable. + ssm->_coroYield = [wssm, &sink]() { MONGO_LOG(3) << "call yield"; - ssm->_dbClient = Client::releaseCurrent(); + if (auto ssmLocked = wssm.lock()) { + ssmLocked->_dbClient = Client::releaseCurrent(); + } else if (haveClient()) { + // Release/destroy the client to avoid leaking it. + (void)Client::releaseCurrent(); + } sink = sink.resume(); }; ssm->_processMessage(std::move(guard)); @@ -787,6 +806,17 @@ void ServiceStateMachine::_cleanupSession(ThreadGuard guard) { _inMessage.reset(); + // Disable coroutine functors early during teardown to prevent any further coroutine + // yield/resume calls racing with destruction of this SSM and its coroutine stack. + if (haveClient()) { + Client::getCurrent()->setCoroutineFunctors(CoroutineFunctors::Unavailable); + } + _coroYield = {}; + _coroResume = {}; + _coroLongResume = {}; + _coroMigrateThreadGroup = {}; + _resumeTask = {}; + // By ignoring the return value of Client::releaseCurrent() we destroy the session. // _dbClient is now nullptr and _dbClientPtr is invalid and should never be accessed. Client::releaseCurrent(); From f6c1d13372eddb18f7daad338f7654191d39bb5d Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Sun, 21 Dec 2025 08:45:28 +0800 Subject: [PATCH 08/15] Fix coroutine yield capturing stack-local continuation ServiceStateMachine stored _coroYield as a member functor but captured &sink from the boost::context::callcc lambda, leaving a dangling reference once the lambda frame changed/ended. This could crash in jump_fcontext() with unreadable backtraces. Store the caller continuation (sink) in a new member _coroSink and implement _coroYield in terms of _coroSink.resume(). Clear _coroSink during reset/cleanup/destruction to avoid resuming stale continuations. --- src/mongo/transport/service_state_machine.cpp | 29 +++++++++++-------- src/mongo/transport/service_state_machine.h | 4 +++ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/mongo/transport/service_state_machine.cpp b/src/mongo/transport/service_state_machine.cpp index 63b3ec4f19..c5ba974279 100644 --- a/src/mongo/transport/service_state_machine.cpp +++ b/src/mongo/transport/service_state_machine.cpp @@ -278,6 +278,7 @@ ServiceStateMachine::ServiceStateMachine(ServiceContext* svcContext, ServiceStateMachine::~ServiceStateMachine() { MONGO_LOG(1) << "ServiceStateMachine::~ServiceStateMachine"; _source = {}; + _coroSink = {}; ::munmap(_coroStack, kCoroStackSize); } @@ -302,6 +303,7 @@ void ServiceStateMachine::reset(ServiceContext* svcContext, _coroLongResume = {}; _coroMigrateThreadGroup = {}; _resumeTask = {}; + _coroSink = {}; _migrating.store(false, std::memory_order_relaxed); _threadGroupId.store(groupId, std::memory_order_relaxed); _owned.store(Ownership::kUnowned); @@ -591,22 +593,24 @@ void ServiceStateMachine::_runNextInGuard(ThreadGuard guard) { if (!ssm) { return std::move(sink); } - // IMPORTANT: Store a yield functor that won't UAF if invoked - // during teardown. If SSM is gone, we still resume `sink` to - // avoid deadlocks/spins in coro::Mutex/ConditionVariable. - ssm->_coroYield = [wssm, &sink]() { - MONGO_LOG(3) << "call yield"; - if (auto ssmLocked = wssm.lock()) { - ssmLocked->_dbClient = Client::releaseCurrent(); - } else if (haveClient()) { - // Release/destroy the client to avoid leaking it. - (void)Client::releaseCurrent(); + // Store sink as a member so yield never captures references to + // stack-local continuation variables. + ssm->_coroSink = std::move(sink); + + // Yield functor: only valid to call while executing on the + // coroutine stack. It resumes the caller continuation. + ssm->_coroYield = [wssm]() { + auto ssmLocked = wssm.lock(); + if (!ssmLocked) { + return; } - sink = sink.resume(); + MONGO_LOG(3) << "call yield"; + ssmLocked->_dbClient = Client::releaseCurrent(); + ssmLocked->_coroSink = ssmLocked->_coroSink.resume(); }; ssm->_processMessage(std::move(guard)); - return std::move(sink); + return std::move(ssm->_coroSink); }); bool migrating = true; @@ -816,6 +820,7 @@ void ServiceStateMachine::_cleanupSession(ThreadGuard guard) { _coroLongResume = {}; _coroMigrateThreadGroup = {}; _resumeTask = {}; + _coroSink = {}; // By ignoring the return value of Client::releaseCurrent() we destroy the session. // _dbClient is now nullptr and _dbClientPtr is invalid and should never be accessed. diff --git a/src/mongo/transport/service_state_machine.h b/src/mongo/transport/service_state_machine.h index 9f10205387..5a395c9c98 100644 --- a/src/mongo/transport/service_state_machine.h +++ b/src/mongo/transport/service_state_machine.h @@ -288,6 +288,10 @@ class ServiceStateMachine : public std::enable_shared_from_this Date: Sun, 21 Dec 2025 08:52:38 +0800 Subject: [PATCH 09/15] Add safety guards + invariants around coroutine yield/resume --- src/mongo/transport/service_state_machine.cpp | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/mongo/transport/service_state_machine.cpp b/src/mongo/transport/service_state_machine.cpp index c5ba974279..446e4a9535 100644 --- a/src/mongo/transport/service_state_machine.cpp +++ b/src/mongo/transport/service_state_machine.cpp @@ -475,6 +475,12 @@ void ServiceStateMachine::_processMessage(ThreadGuard guard) { _serviceExecutor->ongoingCoroutineCountUpdate( _threadGroupId.load(std::memory_order_relaxed), -1); + // The coroutine "yield" contract is only valid while actively running inside the + // callcc() coroutine context. Once request processing completes, disable yielding so + // Client::coroutineFunctors() becomes Unavailable (it checks yieldFuncPtr). + _coroSink = {}; + _coroYield = {}; + // opCtx must be destroyed here so that the operation cannot show // up in currentOp results after the response reaches the client // opCtx.reset(); @@ -557,8 +563,12 @@ void ServiceStateMachine::_runNextInGuard(ThreadGuard guard) { Client::setCurrent(std::move(ssm->_dbClient)); if (ssm->_migrating.load(std::memory_order_relaxed)) { - ssm->_coroResume(); - ssm->_coroYield(); + if (ssm->_coroResume) { + ssm->_coroResume(); + } + if (ssm->_coroYield) { + ssm->_coroYield(); + } } else { ssm->_runResumeProcess(); bool migrating = true; @@ -605,6 +615,10 @@ void ServiceStateMachine::_runNextInGuard(ThreadGuard guard) { return; } MONGO_LOG(3) << "call yield"; + // If these invariants fail, it strongly suggests someone is + // calling yield outside the active coroutine window. + invariant(haveClient()); + invariant(static_cast(ssmLocked->_coroSink)); ssmLocked->_dbClient = Client::releaseCurrent(); ssmLocked->_coroSink = ssmLocked->_coroSink.resume(); }; @@ -786,8 +800,12 @@ void ServiceStateMachine::_migrateThreadGroup(uint16_t threadGroupId) { _coroResume = _serviceExecutor->coroutineResumeFunctor(threadGroupId, _resumeTask); _coroLongResume = _serviceExecutor->coroutineLongResumeFunctor(threadGroupId, _resumeTask); _migrating.store(true, std::memory_order_relaxed); - _coroResume(); - _coroYield(); + if (_coroResume) { + _coroResume(); + } + if (_coroYield) { + _coroYield(); + } #ifdef MONGO_CONFIG_DEBUG_BUILD _owningThread.store(stdx::this_thread::get_id()); #endif From c8ae4bbfe75fb1f461e8c43a58fe52ab028f81bd Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Sun, 21 Dec 2025 09:41:37 +0800 Subject: [PATCH 10/15] Fix coroutine forced_unwind termination --- src/mongo/transport/service_state_machine.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/mongo/transport/service_state_machine.cpp b/src/mongo/transport/service_state_machine.cpp index 446e4a9535..6e589c9c58 100644 --- a/src/mongo/transport/service_state_machine.cpp +++ b/src/mongo/transport/service_state_machine.cpp @@ -53,6 +53,7 @@ #include "mongo/util/net/socket_exception.h" #include "mongo/util/quick_exit.h" +#include #include #include #include @@ -475,12 +476,6 @@ void ServiceStateMachine::_processMessage(ThreadGuard guard) { _serviceExecutor->ongoingCoroutineCountUpdate( _threadGroupId.load(std::memory_order_relaxed), -1); - // The coroutine "yield" contract is only valid while actively running inside the - // callcc() coroutine context. Once request processing completes, disable yielding so - // Client::coroutineFunctors() becomes Unavailable (it checks yieldFuncPtr). - _coroSink = {}; - _coroYield = {}; - // opCtx must be destroyed here so that the operation cannot show // up in currentOp results after the response reaches the client // opCtx.reset(); @@ -660,6 +655,9 @@ void ServiceStateMachine::_runNextInGuard(ThreadGuard guard) { } return; + } catch (const boost::context::detail::forced_unwind&) { + // Boost.Context uses forced_unwind to unwind stacks safely. It must never be swallowed. + throw; } catch (const DBException& e) { // must be right above std::exception to avoid catching subclasses log() << "DBException handling request, closing client connection: " << redact(e); From 3b25393a26ec7496cddb5139243343347785b0a8 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Sun, 21 Dec 2025 08:26:29 +0000 Subject: [PATCH 11/15] change new range fill factor --- src/mongo/db/modules/eloq/data_substrate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mongo/db/modules/eloq/data_substrate b/src/mongo/db/modules/eloq/data_substrate index 8c9314aa4e..7c4c31db63 160000 --- a/src/mongo/db/modules/eloq/data_substrate +++ b/src/mongo/db/modules/eloq/data_substrate @@ -1 +1 @@ -Subproject commit 8c9314aa4edb6e70a47761cc27c93a7ad4f8551b +Subproject commit 7c4c31db632cfd710865208605afd90f590cb424 From 60140f228a5559323973b7b242bd564670f670a9 Mon Sep 17 00:00:00 2001 From: githubzilla Date: Sun, 21 Dec 2025 19:07:38 +0800 Subject: [PATCH 12/15] Update data_substrate --- src/mongo/db/modules/eloq/data_substrate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mongo/db/modules/eloq/data_substrate b/src/mongo/db/modules/eloq/data_substrate index 7c4c31db63..2fec936c4a 160000 --- a/src/mongo/db/modules/eloq/data_substrate +++ b/src/mongo/db/modules/eloq/data_substrate @@ -1 +1 @@ -Subproject commit 7c4c31db632cfd710865208605afd90f590cb424 +Subproject commit 2fec936c4a788ba715b0c8641f0e88b555600968 From 09233cb4e701462b539399fea20891810a567027 Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Tue, 23 Dec 2025 00:07:36 +0800 Subject: [PATCH 13/15] Revert "Update data_substrate" This reverts commit 60140f228a5559323973b7b242bd564670f670a9. --- src/mongo/db/modules/eloq/data_substrate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mongo/db/modules/eloq/data_substrate b/src/mongo/db/modules/eloq/data_substrate index 2fec936c4a..7c4c31db63 160000 --- a/src/mongo/db/modules/eloq/data_substrate +++ b/src/mongo/db/modules/eloq/data_substrate @@ -1 +1 @@ -Subproject commit 2fec936c4a788ba715b0c8641f0e88b555600968 +Subproject commit 7c4c31db632cfd710865208605afd90f590cb424 From 3d34a65333bb2422b90f87249f484fa23e7784b8 Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Tue, 23 Dec 2025 14:46:45 +0800 Subject: [PATCH 14/15] Revert "Revert "Update data_substrate"" This reverts commit 09233cb4e701462b539399fea20891810a567027. --- src/mongo/db/modules/eloq/data_substrate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mongo/db/modules/eloq/data_substrate b/src/mongo/db/modules/eloq/data_substrate index 7c4c31db63..2fec936c4a 160000 --- a/src/mongo/db/modules/eloq/data_substrate +++ b/src/mongo/db/modules/eloq/data_substrate @@ -1 +1 @@ -Subproject commit 7c4c31db632cfd710865208605afd90f590cb424 +Subproject commit 2fec936c4a788ba715b0c8641f0e88b555600968 From 2696c5e7d5bcf41d86ad2fd03662ca1143ebe956 Mon Sep 17 00:00:00 2001 From: Chen Zhao Date: Thu, 25 Dec 2025 18:31:11 +0800 Subject: [PATCH 15/15] update submodule: adapt to boost::context asan position change --- src/mongo/db/modules/eloq/data_substrate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mongo/db/modules/eloq/data_substrate b/src/mongo/db/modules/eloq/data_substrate index 2fec936c4a..372542f747 160000 --- a/src/mongo/db/modules/eloq/data_substrate +++ b/src/mongo/db/modules/eloq/data_substrate @@ -1 +1 @@ -Subproject commit 2fec936c4a788ba715b0c8641f0e88b555600968 +Subproject commit 372542f747511ba8541e3310c48678509870b9e6