From f189ce0108adc2ed56cafd4538a0e19fc845cc1f 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;