From 7f87a839f97ee8d93e8213dfd41c35436411c077 Mon Sep 17 00:00:00 2001 From: Jeremy Lorelli Date: Wed, 24 Jun 2026 17:01:05 -0700 Subject: [PATCH] libcom: Make EPICS_ABORT_ON_ASSERT affect cantProceed EPICS_ABORT_ON_ASSERT was introduced to kill the entire IOC instead of suspending an individual thread on assert failure. This behavior, however, was not implemented for cantProceed, which left most of the epicsMustBlah APIs with the suspention behavior (except for a couple APIs that called assert() instead). --- modules/libcom/src/misc/cantProceed.c | 19 +++++++++++++++---- modules/libcom/src/osi/epicsMutex.h | 12 ++++++------ .../libcom/src/osi/os/RTEMS-score/osdTime.cpp | 5 +++-- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/modules/libcom/src/misc/cantProceed.c b/modules/libcom/src/misc/cantProceed.c index 7afb4750c..19faca45b 100644 --- a/modules/libcom/src/misc/cantProceed.c +++ b/modules/libcom/src/misc/cantProceed.c @@ -15,6 +15,7 @@ #include #include "errlog.h" +#include "envDefs.h" #include "cantProceed.h" #include "epicsThread.h" #include "epicsStackTrace.h" @@ -53,20 +54,30 @@ LIBCOM_API void * mallocMustSucceed(size_t size, const char *msg) LIBCOM_API void cantProceed(const char *msg, ...) { + int shouldAbort = 0; va_list pvar; va_start(pvar, msg); if (msg) errlogVprintf(msg, pvar); va_end(pvar); - errlogPrintf(ANSI_RED("CRITICAL ERROR") " Thread %s (%p) can't proceed, suspending.\n", - epicsThreadGetNameSelf(), epicsThreadGetIdSelf()); + envGetBoolConfigParam(&EPICS_ABORT_ON_ASSERT, &shouldAbort); + + errlogPrintf(ANSI_RED("CRITICAL ERROR") " Thread %s (%p) can't proceed, %s.\n", + epicsThreadGetNameSelf(), epicsThreadGetIdSelf(), shouldAbort ? "aborting" : "suspending"); epicsStackTrace(); errlogFlush(); epicsThreadSleep(1.0); - while (1) - epicsThreadSuspendSelf(); + + if (shouldAbort) { + errlogPrintf("cantProceed() Calling abort()\n"); + errlogFlush(); + abort(); + } else { + while (1) + epicsThreadSuspendSelf(); + } } diff --git a/modules/libcom/src/osi/epicsMutex.h b/modules/libcom/src/osi/epicsMutex.h index c88f57e74..2b0e1ec40 100644 --- a/modules/libcom/src/osi/epicsMutex.h +++ b/modules/libcom/src/osi/epicsMutex.h @@ -213,12 +213,12 @@ LIBCOM_API epicsMutexLockStatus epicsStdCall epicsMutexLock( * This routine does not return if the identifier is invalid. * \param ID The mutex identifier. **/ -#define epicsMutexMustLock(ID) { \ - epicsMutexLockStatus status = epicsMutexLock(ID); \ - if(status != epicsMutexLockOK) { \ - cantProceed("epicsMutexMustLock() failed at %s:%d", \ - __FILE__, __LINE__); \ - } \ +#define epicsMutexMustLock(ID) { \ + epicsMutexLockStatus status = epicsMutexLock(ID); \ + if(status != epicsMutexLockOK) { \ + cantProceed("epicsMutexMustLock() failed at %s:%d\n", \ + __FILE__, __LINE__); \ + } \ } /**\brief Similar to epicsMutexLock() except that the call returns immediately, diff --git a/modules/libcom/src/osi/os/RTEMS-score/osdTime.cpp b/modules/libcom/src/osi/os/RTEMS-score/osdTime.cpp index b8527d756..36fdeb252 100644 --- a/modules/libcom/src/osi/os/RTEMS-score/osdTime.cpp +++ b/modules/libcom/src/osi/os/RTEMS-score/osdTime.cpp @@ -15,19 +15,20 @@ #define EPICS_EXPOSE_LIBCOM_MONOTONIC_PRIVATE #include -#include #include #include #include #include #include -#include #include "epicsTime.h" #include "osdTime.h" #include "osiNTPTime.h" #include "osiClockTime.h" #include "generalTimeSup.h" +#include +#include + extern "C" { extern rtems_interval rtemsTicksPerSecond;