Experimental Physics and Industrial Control System
Hello Lewis,
FWIW, I had a look at the main trunk in CVS and it appears that most CA
messages print using the following member function - which either calls the
user's message printing callback or else calls the "vfprintf ( stderr, ...
)" function in the C standard library.
int ca_client_context :: varArgsPrintFormated (
const char *pformat, va_list args ) const // X aCC 361
{
caPrintfFunc * pFunc;
{
Guard guard ( this->mutex );
pFunc = this->pVPrintfFunc;
}
if ( pFunc ) {
return ( *pFunc ) ( pformat, args );
}
else {
return :: vfprintf ( stderr, pformat, args );
}
}
I also recall that during the preparation of R3.14 it was a huge hassle that
the code could not own a lock when it was calling the CA message generating
function (because it's not a good idea to hold a lock when calling the
user's callback to avoid deadlocks). So in certain tricky situations I
compromised and called "errPrintf()". Furthermore, after a quick look in the
source, it would appear that the errlog system *is* printing to stdout. So
that might explain how certain error messages are ending up on stdout.
LOCAL void errlogThread(void)
{
listenerNode *plistenerNode;
int noConsoleMessage;
char *pmessage;
epicsAtExit(exitHandler,0);
while(TRUE) {
epicsEventMustWait(pvtData.waitForWork);
if(pvtData.atExit) break;
while((pmessage = msgbufGetSend(&noConsoleMessage))) {
if(pvtData.atExit) break;
epicsMutexMustLock(pvtData.listenerLock);
if(pvtData.toConsole && !noConsoleMessage) {
fprintf(stdout,"%s",pmessage);
fflush(stdout);
}
plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList);
while(plistenerNode) {
(*plistenerNode->listener)(plistenerNode->pPrivate,
pmessage);
plistenerNode = (listenerNode
*)ellNext(&plistenerNode->node);
}
epicsMutexUnlock(pvtData.listenerLock);
msgbufFreeSend();
}
if(pvtData.atExit) break;
if(epicsEventTryWait(pvtData.flush)!=epicsEventWaitOK) continue;
epicsThreadSleep(.2); /*just wait an extra .2 seconds*/
epicsEventSignal(pvtData.waitForFlush);
}
errlogCleanup();
epicsEventSignal(pvtData.waitForExit);
}
Jeff
> -----Original Message-----
> From: J. Lewis Muir [mailto:[email protected]]
> Sent: Friday, May 02, 2008 1:10 PM
> To: Ralph Lange
> Cc: Jeff Hill
> Subject: camonitor prints CA errors to stdout rather than stderr
>
> Hi, Ralph.
>
> Thanks for writing such a useful tool in camonitor. I'm using camonitor
to
> do some simple logging of some EPICS PV values to a file by redirecting
> camonitor's stdout to a file. Unfortunately, CA error messages are
getting
> printed on stdout also. I think this is a bug; CA error messages should
be
> printed on stderr instead.
>
> I've written some software to parse these camonitor logs, but with CA
error
> messages printed to stdout, they can corrupt the camonitor output being
> logged since they could appear at an arbitrary location. If they were
> atomically written on their own lines I could trivially make my software
> ignore them, but when they can appear interleaved in an arbitrary way with
> the normal camonitor output, it makes it impractical to parse. The
> attached corrupted.log gives an example of this.
>
> I've attached a patch, use-stderr.patch, for the EPICS 3.14.9 base file
>
> src/catools/camonitor.c
>
> that replaces the CA printf handler with one that prints to stderr.
> Does this seem like a reasonable fix to you?
>
> According to the CA reference manual at
>
> src/ca/CAref.html
>
> this change to camonitor.c should not be necessary. In the description
for
> the ca_replace_printf_handler function, it says the default handler uses
> fprintf to send messages to stderr. This would be great, but it is not
> true; the messages are being printed on stdout. I'd be quite happy if
this
> were changed in CA somewhere making my change to camonitor.c unnecessary.
>
> Using the unmodified camonitor, I ran the following from a Bourne shell
>
> camonitor 13ADSC1:det1:ADSCState | tee state.log
>
> The PV 13ADSC1:det1:ADSCState is provided by a soft IOC running on my
> computer. I then typed "exit" at the soft IOC's console, it exited, and I
> started it again. The resulting state.log file is attached. It contains
> the stdout of the camonitor program and unfortunately also contains the CA
> exception message that was written to stdout.
>
> After modifying camonitor in the way my use-stderr.patch does, I performed
> the same experiment again by running
>
> camonitor 13ADSC1:det1:ADSCState | tee state2.log
>
> The resulting state2.log file is attached. This time it had the correct
> behavior; no CA exception message was written to stdout.
>
> I of course see the CA error message printed on the console where I ran
> camonitor both times.
>
> Thanks,
>
> Lewis
>
> --
> J. Lewis Muir
> Software Engineer
> IMCA-CAT/CARS
- Replies:
- Re: camonitor prints CA errors to stdout rather than stderr J. Lewis Muir
- Navigate by Date:
- Prev:
Re: Unresolved symbol: rtemsTicksPerSecond_double Andrew Johnson
- Next:
Re: camonitor prints CA errors to stdout rather than stderr J. Lewis Muir
- Index:
2002
2003
2004
2005
2006
2007
<2008>
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: Unresolved symbol: rtemsTicksPerSecond_double Andrew Johnson
- Next:
Re: camonitor prints CA errors to stdout rather than stderr J. Lewis Muir
- Index:
2002
2003
2004
2005
2006
2007
<2008>
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024