From f4528ff5e189e6e52054634b0ac396a5685b5c9d Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 1 Mar 2011 15:03:33 -0600 Subject: [PATCH] libCom: Fix msgbufGetNode() in errlog.c Systems that generate large numbers of errlog messages or have a slow message listener could overwrite older messages in the message buffer after the buffer wraps. This also corrects and annotates the test code to describe what's being checked. --- src/libCom/error/errlog.c | 6 ++++-- src/libCom/test/epicsErrlogTest.c | 20 +++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/libCom/error/errlog.c b/src/libCom/error/errlog.c index 36399a119..322eb9c4f 100644 --- a/src/libCom/error/errlog.c +++ b/src/libCom/error/errlog.c @@ -534,8 +534,10 @@ static msgNode *msgbufGetNode(void) char *plimit = pbuffer + pvtData.buffersize; pnextFree = plast->message + adjustToWorstCaseAlignment(plast->length); - if (pfirst <= plast && - pnextFree + pvtData.msgNeeded > plimit) { + if (pfirst > plast) { + plimit = (char *)pfirst; + } + else if (pnextFree + pvtData.msgNeeded > plimit) { pnextFree = pbuffer; /* Hit end, wrap to start */ plimit = (char *)pfirst; } diff --git a/src/libCom/test/epicsErrlogTest.c b/src/libCom/test/epicsErrlogTest.c index c96013313..08389e438 100644 --- a/src/libCom/test/epicsErrlogTest.c +++ b/src/libCom/test/epicsErrlogTest.c @@ -260,29 +260,31 @@ MAIN(epicsErrlogTest) for (i = 0; i < N; i++) { errlogPrintfNoConsole(msg); } + epicsThreadSleep(0.1); /* should really be a second Event */ testOk1(pvt.count == 0); - epicsThreadSleep(0.1); /* should really be a second Event */ - - pvt.jam = -2; /* Block before #th message */ + /* Extract the first 2 messages, 2*(sizeof(msgNode) + 128) bytes */ + pvt.jam = -2; epicsEventSignal(pvt.jammer); epicsThreadSleep(0.1); - testDiag("Drain %u messages", pvt.count); + testDiag("Drained %u messages", pvt.count); testOk1(pvt.count == 2); - testDiag("Add two more (%d total)", (int) N+2); - errlogPrintfNoConsole(msg); + /* The buffer has space for 1 more message: sizeof(msgNode) + 256 bytes */ + errlogPrintfNoConsole(msg); /* Use up that space */ + + testDiag("Overflow the buffer"); errlogPrintfNoConsole(msg); testOk1(pvt.count == 2); - epicsEventSignal(pvt.jammer); + epicsEventSignal(pvt.jammer); /* Empty */ errlogFlush(); - testDiag("Logged %u messages", pvt.count); - testOk1(pvt.count == N+2); + testDiag("Logged %u messages", pvt.count); + testOk1(pvt.count == N+1); /* Clean up */ errlogRemoveListener(&logClient);