From 35898f1ae080eca2230aa5cdd5052d97340ab19a Mon Sep 17 00:00:00 2001 From: Dundy Pasupuleti Date: Fri, 2 Oct 2026 11:16:41 -0400 Subject: [PATCH] fix: keep is_ready error_string_shm alive until parent ack ProcessUserModelReadinessRequest declared error_string_shm inside the has_exception block, so the unique_ptr freed the Boost shm allocation before the stub notified the parent. Parent LoadFromSharedMemory then touched a freed handle, corrupting the pool free-list and hanging the stub (~98% CPU) on is_ready() exception / non-boolean paths. Widen error_string_shm to function scope so it survives notify -> parent Load -> ack, matching GetCUDAMemoryPoolAddress in the same file. Fixes triton-inference-server/server#8978 Signed-off-by: Dundy Pasupuleti --- src/pb_stub.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pb_stub.cc b/src/pb_stub.cc index 92b5bbd7..27e0e61c 100644 --- a/src/pb_stub.cc +++ b/src/pb_stub.cc @@ -1632,6 +1632,10 @@ Stub::ProcessUserModelReadinessRequest(std::unique_ptr& ipc_message) bool function_exists = false; bool has_exception = false; std::string error_string; + // Keep error_string_shm alive until after parent ack so the parent can + // LoadFromSharedMemory the handle before this function returns and frees it. + // Same lifetime pattern as GetCUDAMemoryPoolAddress above. + std::unique_ptr error_string_shm; try { py::gil_scoped_acquire acquire; @@ -1673,7 +1677,6 @@ Stub::ProcessUserModelReadinessRequest(std::unique_ptr& ipc_message) readiness_payload->error = 0; if (has_exception) { - std::unique_ptr error_string_shm; LOG_IF_EXCEPTION( error_string_shm = PbString::Create(shm_pool_, error_string)); if (error_string_shm != nullptr) { @@ -1689,7 +1692,8 @@ Stub::ProcessUserModelReadinessRequest(std::unique_ptr& ipc_message) readiness_payload->waiting_on_stub = true; ipc_message->ResponseCondition()->notify_all(); - // Wait for parent ack with timeout to avoid deadlock + // Wait for parent ack with timeout to avoid deadlock. Required so + // error_string_shm stays alive until the parent finishes reading it. boost::posix_time::ptime timeout = boost::get_system_time() + boost::posix_time::milliseconds(kUserModelReadinessTimeoutMs);