From 0e89f68662647f0808d3ff9d23a53a9829d1652d Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 20 Nov 2025 13:23:33 +0100 Subject: [PATCH] DPL: fix thread safety of slot allocation in runtime_error_f --- Framework/Foundation/src/RuntimeError.cxx | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Framework/Foundation/src/RuntimeError.cxx b/Framework/Foundation/src/RuntimeError.cxx index 6f31fb40b86f5..7d31389a9641c 100644 --- a/Framework/Foundation/src/RuntimeError.cxx +++ b/Framework/Foundation/src/RuntimeError.cxx @@ -60,8 +60,11 @@ RuntimeError& error_from_ref(RuntimeErrorRef ref) RuntimeErrorRef runtime_error_f(const char* format, ...) { int i = 0; - bool expected = false; - while (gErrorBooking[i].compare_exchange_strong(expected, true) == false) { + while (true) { + bool expected = false; + if (gErrorBooking[i].compare_exchange_strong(expected, true) == true) { + break; + } ++i; if (i >= RuntimeError::MAX_RUNTIME_ERRORS) { throw std::runtime_error("Too many o2::framework::runtime_error thrown without proper cleanup."); @@ -78,11 +81,18 @@ RuntimeErrorRef runtime_error_f(const char* format, ...) RuntimeErrorRef runtime_error(const char* s) { int i = 0; - bool expected = false; - while (gErrorBooking[i].compare_exchange_strong(expected, true) == false) { + while (true) { + bool expected = false; + if (gErrorBooking[i].compare_exchange_strong(expected, true) == true) { + break; + } ++i; + if (i >= RuntimeError::MAX_RUNTIME_ERRORS) { + throw std::runtime_error("Too many o2::framework::runtime_error thrown without proper cleanup."); + } } - strncpy(gError[i].what, s, RuntimeError::MAX_RUNTIME_ERROR_SIZE); + strncpy(gError[i].what, s, RuntimeError::MAX_RUNTIME_ERROR_SIZE - 1); + gError[i].what[RuntimeError::MAX_RUNTIME_ERROR_SIZE - 1] = 0; gError[i].maxBacktrace = canDumpBacktrace() ? backtrace(gError[i].backtrace, BacktraceHelpers::MAX_BACKTRACE_SIZE) : 0; return RuntimeErrorRef{i}; }