From a28a561d8a3e3eae25c2cfc33adaaf8c4ea7deb7 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 23 Jun 2014 16:28:18 -0400 Subject: [PATCH] epicsExit: optional debug printing Add a flag to cause a string to be printed before each handler is run to show the order. --- src/ioc/misc/dbCore.dbd | 3 +++ src/libCom/misc/epicsExit.c | 25 ++++++++++++++++++++----- src/libCom/misc/epicsExit.h | 3 ++- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/ioc/misc/dbCore.dbd b/src/ioc/misc/dbCore.dbd index fac0fd674..3b22f4663 100644 --- a/src/ioc/misc/dbCore.dbd +++ b/src/ioc/misc/dbCore.dbd @@ -5,6 +5,9 @@ # This file provides iocsh access to variables that control some lesser-used # and debugging features of the IOC database code. +# show epicsAtExit callbacks as they are run +variable(atExitDebug,int) + # Access security subroutines variable(asCaDebug,int) diff --git a/src/libCom/misc/epicsExit.c b/src/libCom/misc/epicsExit.c index 453378d36..6ae9dffd5 100644 --- a/src/libCom/misc/epicsExit.c +++ b/src/libCom/misc/epicsExit.c @@ -23,7 +23,9 @@ */ #include +#include #include +#include #define epicsExportSharedSymbols #include "ellLib.h" @@ -36,12 +38,15 @@ typedef struct exitNode { ELLNODE node; epicsExitFunc func; void *arg; + char name[1]; }exitNode; typedef struct exitPvt { ELLLIST list; } exitPvt; +int atExitDebug = 0; + static epicsThreadOnceId exitPvtOnce = EPICS_THREAD_ONCE_INIT; static exitPvt * pExitPvtPerProcess = 0; static epicsMutexId exitPvtLock = 0; @@ -75,6 +80,10 @@ static void epicsExitCallAtExitsPvt(exitPvt *pep) { exitNode *pexitNode; while ( ( pexitNode = (exitNode *) ellLast ( & pep->list ) ) ) { + if (atExitDebug && pexitNode->name[0]) + fprintf(stderr, "atExit %s(%p)\n", pexitNode->name, pexitNode->arg); + else if(atExitDebug) + fprintf(stderr, "atExit %p(%p)\n", pexitNode->func, pexitNode->arg); pexitNode->func ( pexitNode->arg ); ellDelete ( & pep->list, & pexitNode->node ); free ( pexitNode ); @@ -109,14 +118,16 @@ epicsShareFunc void epicsExitCallAtThreadExits(void) } } -static int epicsAtExitPvt(exitPvt *pep, epicsExitFunc func, void *arg) +static int epicsAtExitPvt(exitPvt *pep, epicsExitFunc func, void *arg, const char *name) { int status = -1; - exitNode * pExitNode + exitNode * pExitNode = calloc ( 1, sizeof( *pExitNode ) + (name?strlen(name):0) ); = calloc ( 1, sizeof( *pExitNode ) ); if ( pExitNode ) { pExitNode->func = func; pExitNode->arg = arg; + if(name) + strcpy(pExitNode->name, name); ellAdd ( & pep->list, & pExitNode->node ); status = 0; } @@ -135,16 +146,16 @@ epicsShareFunc int epicsAtThreadExit(epicsExitFunc func, void *arg) } epicsThreadPrivateSet ( exitPvtPerThread, pep ); } - return epicsAtExitPvt ( pep, func, arg ); + return epicsAtExitPvt ( pep, func, arg, NULL ); } -epicsShareFunc int epicsAtExit(epicsExitFunc func, void *arg) +epicsShareFunc int epicsAtExit3(epicsExitFunc func, void *arg, const char* name) { int status = -1; epicsThreadOnce ( & exitPvtOnce, exitPvtOnceFunc, 0 ); epicsMutexMustLock ( exitPvtLock ); if ( pExitPvtPerProcess ) { - status = epicsAtExitPvt ( pExitPvtPerProcess, func, arg ); + status = epicsAtExitPvt ( pExitPvtPerProcess, func, arg, name ); } epicsMutexUnlock ( exitPvtLock ); return status; @@ -156,3 +167,7 @@ epicsShareFunc void epicsExit(int status) epicsThreadSleep(1.0); exit(status); } + +#include "epicsExport.h" + +epicsExportAddress(int,atExitDebug); diff --git a/src/libCom/misc/epicsExit.h b/src/libCom/misc/epicsExit.h index 2fb33f129..e64316010 100644 --- a/src/libCom/misc/epicsExit.h +++ b/src/libCom/misc/epicsExit.h @@ -19,7 +19,8 @@ typedef void (*epicsExitFunc)(void *arg); epicsShareFunc void epicsExit(int status); epicsShareFunc void epicsExitCallAtExits(void); -epicsShareFunc int epicsAtExit(epicsExitFunc func, void *arg); +epicsShareFunc int epicsAtExit3(epicsExitFunc func, void *arg, const char* name); +#define epicsAtExit(F,A) epicsAtExit3(F,A,#F) epicsShareFunc void epicsExitCallAtThreadExits(void); epicsShareFunc int epicsAtThreadExit(epicsExitFunc func, void *arg);