EPICS Home

Experimental Physics and Industrial Control System


 
2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: camonitor prints CA errors to stdout rather than stderr
From: "Jeff Hill" <[email protected]>
To: "'J. Lewis Muir'" <[email protected]>, "'Ralph Lange'" <[email protected]>
Cc: "'EPICS core-talk'" <[email protected]>, "'EPICS Tech-Talk'" <[email protected]>
Date: Fri, 2 May 2008 15:55:38 -0600
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  <20082009  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  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024