Merged Michael's valgrind branch

This commit is contained in:
Andrew Johnson
2016-02-08 18:01:59 -06:00
11 changed files with 6734 additions and 13 deletions

View File

@@ -9,9 +9,14 @@
TOP = ../..
include $(TOP)/configure/CONFIG
# Uncomment this to remove the (benign) valgrind helper stubs
#USR_CFLAGS += -DNVALGRIND
SRC = $(TOP)/src
LIBCOM = $(SRC)/libCom
INC += valgrind/valgrind.h
include $(LIBCOM)/as/Makefile
include $(LIBCOM)/bucketLib/Makefile
include $(LIBCOM)/calc/Makefile

View File

@@ -19,6 +19,15 @@
#include <stdio.h>
#include <string.h>
#include "valgrind/valgrind.h"
#ifndef NVALGRIND
/* buffer around allocations to detect out of bounds access */
#define REDZONE sizeof(double)
#else
#define REDZONE 0
#endif
#define epicsExportSharedSymbols
#include "epicsMutex.h"
#include "ellLib.h"
@@ -70,13 +79,17 @@ int epicsShareAPI dbmfInit(size_t size, int chunkItems)
pdbmfPvt->lock = epicsMutexMustCreate();
/*allign to at least a double*/
pdbmfPvt->size = size + size%sizeof(double);
pdbmfPvt->allocSize = pdbmfPvt->size + sizeof(itemHeader);
/* layout is
* | itemHeader | REDZONE | size | REDZONE |
*/
pdbmfPvt->allocSize = pdbmfPvt->size + sizeof(itemHeader) + 2*REDZONE;
pdbmfPvt->chunkItems = chunkItems;
pdbmfPvt->chunkSize = pdbmfPvt->allocSize * pdbmfPvt->chunkItems;
pdbmfPvt->nAlloc = 0;
pdbmfPvt->nFree = 0;
pdbmfPvt->nGtSize = 0;
pdbmfPvt->freeList = NULL;
VALGRIND_CREATE_MEMPOOL(pdbmfPvt, REDZONE, 0);
return(0);
}
@@ -124,7 +137,7 @@ void* epicsShareAPI dbmfMalloc(size_t size)
pitemHeader = (itemHeader *)pnextFree;
pitemHeader->pchunkNode->nNotFree += 1;
} else {
pmem = malloc(sizeof(itemHeader) + size);
pmem = malloc(sizeof(itemHeader) + 2*REDZONE + size);
if(!pmem) {
epicsMutexUnlock(pdbmfPvt->lock);
printf("dbmfMalloc malloc failed\n");
@@ -133,12 +146,14 @@ void* epicsShareAPI dbmfMalloc(size_t size)
pdbmfPvt->nAlloc++;
pdbmfPvt->nGtSize++;
pitemHeader = (itemHeader *)pmem;
pitemHeader->pchunkNode = NULL;
pitemHeader->pchunkNode = NULL; /* not part of free list */
if(dbmfDebug) printf("dbmfMalloc: size %lu mem %p\n",
(unsigned long)size,pmem);
}
epicsMutexUnlock(pdbmfPvt->lock);
return((void *)(pmem + sizeof(itemHeader)));
pmem += sizeof(itemHeader) + REDZONE;
VALGRIND_MEMPOOL_ALLOC(pdbmfPvt, pmem, size);
return((void *)pmem);
}
char * epicsShareAPI dbmfStrdup(unsigned char *str)
@@ -160,7 +175,8 @@ void epicsShareAPI dbmfFree(void* mem)
printf("dbmfFree called but dbmfInit never called\n");
return;
}
pmem -= sizeof(itemHeader);
VALGRIND_MEMPOOL_FREE(pdbmfPvt, mem);
pmem -= sizeof(itemHeader) + REDZONE;
epicsMutexMustLock(pdbmfPvt->lock);
pitemHeader = (itemHeader *)pmem;
if(!pitemHeader->pchunkNode) {

View File

@@ -15,6 +15,15 @@
#include <stdlib.h>
#include <stddef.h>
#include "valgrind/valgrind.h"
#ifndef NVALGRIND
/* buffer around allocations to detect out of bounds access */
#define REDZONE sizeof(double)
#else
#define REDZONE 0
#endif
#define epicsExportSharedSymbols
#include "cantProceed.h"
#include "epicsMutex.h"
@@ -47,6 +56,7 @@ epicsShareFunc void epicsShareAPI
pfl->nBlocksAvailable = 0u;
pfl->lock = epicsMutexMustCreate();
*ppvt = (void *)pfl;
VALGRIND_CREATE_MEMPOOL(pfl, REDZONE, 0);
return;
}
@@ -78,7 +88,14 @@ epicsShareFunc void * epicsShareAPI freeListMalloc(void *pvt)
epicsMutexMustLock(pfl->lock);
ptemp = pfl->head;
if(ptemp==0) {
ptemp = (void *)malloc(pfl->nmalloc*pfl->size);
/* layout of each block. nmalloc+1 REDZONEs for nmallocs.
* The first sizeof(void*) bytes are used to store a pointer
* to the next free block.
*
* | RED | size0 ------ | RED | size1 | ... | RED |
* | | next | ----- |
*/
ptemp = (void *)malloc(pfl->nmalloc*(pfl->size+REDZONE)+REDZONE);
if(ptemp==0) {
epicsMutexUnlock(pfl->lock);
return(0);
@@ -89,15 +106,17 @@ epicsShareFunc void * epicsShareAPI freeListMalloc(void *pvt)
free(ptemp);
return(0);
}
pallocmem->memory = ptemp;
pallocmem->memory = ptemp; /* real allocation */
ptemp += REDZONE; /* skip first REDZONE */
if(pfl->mallochead)
pallocmem->next = pfl->mallochead;
pfl->mallochead = pallocmem;
for(i=0; i<pfl->nmalloc; i++) {
ppnext = ptemp;
VALGRIND_MEMPOOL_ALLOC(pfl, ptemp, sizeof(void*));
*ppnext = pfl->head;
pfl->head = ptemp;
ptemp = ((char *)ptemp) + pfl->size;
ptemp = ((char *)ptemp) + pfl->size+REDZONE;
}
ptemp = pfl->head;
pfl->nBlocksAvailable += pfl->nmalloc;
@@ -106,6 +125,8 @@ epicsShareFunc void * epicsShareAPI freeListMalloc(void *pvt)
pfl->head = *ppnext;
pfl->nBlocksAvailable--;
epicsMutexUnlock(pfl->lock);
VALGRIND_MEMPOOL_FREE(pfl, ptemp);
VALGRIND_MEMPOOL_ALLOC(pfl, ptemp, pfl->size);
return(ptemp);
# endif
}
@@ -119,6 +140,9 @@ epicsShareFunc void epicsShareAPI freeListFree(void *pvt,void*pmem)
# else
void **ppnext;
VALGRIND_MEMPOOL_FREE(pvt, pmem);
VALGRIND_MEMPOOL_ALLOC(pvt, pmem, sizeof(void*));
epicsMutexMustLock(pfl->lock);
ppnext = pmem;
*ppnext = pfl->head;
@@ -134,6 +158,8 @@ epicsShareFunc void epicsShareAPI freeListCleanup(void *pvt)
allocMem *phead;
allocMem *pnext;
VALGRIND_DESTROY_MEMPOOL(pvt);
phead = pfl->mallochead;
while(phead) {
pnext = phead->next;

View File

@@ -35,6 +35,8 @@
#include "cantProceed.h"
#include "epicsExit.h"
void epicsMutexCleanup(void);
typedef struct exitNode {
ELLNODE node;
epicsExitFunc func;
@@ -113,6 +115,8 @@ epicsShareFunc void epicsExitCallAtExits(void)
epicsExitCallAtExitsPvt ( pep );
destroyExitPvt ( pep );
}
/* Handle specially to avoid circular reference */
epicsMutexCleanup();
}
epicsShareFunc void epicsExitCallAtThreadExits(void)

View File

@@ -28,6 +28,7 @@
#define epicsExportSharedSymbols
#include "epicsStdio.h"
#include "epicsThread.h"
#include "valgrind/valgrind.h"
#include "ellLib.h"
#include "errlog.h"
#include "epicsMutex.h"
@@ -85,6 +86,7 @@ epicsMutexId epicsShareAPI epicsMutexOsiCreate(
firstTime=0;
ellInit(&mutexList);
ellInit(&freeList);
VALGRIND_CREATE_MEMPOOL(&freeList, 0, 0);
epicsMutexGlobalLock = epicsMutexOsdCreate();
}
id = epicsMutexOsdCreate();
@@ -98,9 +100,11 @@ epicsMutexId epicsShareAPI epicsMutexOsiCreate(
reinterpret_cast < epicsMutexParm * > ( ellFirst(&freeList) );
if(pmutexNode) {
ellDelete(&freeList,&pmutexNode->node);
VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode);
} else {
pmutexNode = static_cast < epicsMutexParm * > ( calloc(1,sizeof(epicsMutexParm)) );
}
VALGRIND_MEMPOOL_ALLOC(&freeList, pmutexNode, sizeof(epicsMutexParm));
pmutexNode->id = id;
# ifdef LOG_LAST_OWNER
pmutexNode->lastOwner = 0;
@@ -127,6 +131,8 @@ void epicsShareAPI epicsMutexDestroy(epicsMutexId pmutexNode)
assert ( lockStat == epicsMutexLockOK );
ellDelete(&mutexList,&pmutexNode->node);
epicsMutexOsdDestroy(pmutexNode->id);
VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode);
VALGRIND_MEMPOOL_ALLOC(&freeList, &pmutexNode->node, sizeof(pmutexNode->node));
ellAdd(&freeList,&pmutexNode->node);
epicsMutexOsdUnlock(epicsMutexGlobalLock);
}
@@ -162,6 +168,26 @@ epicsMutexLockStatus epicsShareAPI epicsMutexTryLock(
return status;
}
/* Empty the freeList.
* Called from epicsExit.c, but not via epicsAtExit()
* to avoid the possibility of a circular reference.
*/
extern "C"
void epicsMutexCleanup(void)
{
ELLNODE *cur;
epicsMutexLockStatus lockStat =
epicsMutexOsdLock(epicsMutexGlobalLock);
assert ( lockStat == epicsMutexLockOK );
while((cur=ellGet(&freeList))!=NULL) {
VALGRIND_MEMPOOL_FREE(&freeList, cur);
free(cur);
}
epicsMutexOsdUnlock(epicsMutexGlobalLock);
}
void epicsShareAPI epicsMutexShow(
epicsMutexId pmutexNode, unsigned int level)
{

View File

@@ -25,6 +25,7 @@
#include "epicsStdioRedirect.h"
#include "epicsThread.h"
#include "epicsMutex.h"
#include "valgrind/valgrind.h"
#include "errlog.h"
#include "ellLib.h"
#include "errMdef.h"
@@ -130,9 +131,15 @@ static void twdTask(void *arg)
static void twdShutdown(void *arg)
{
ELLNODE *cur;
twdCtl = twdctlExit;
epicsEventSignal(loopEvent);
epicsEventWait(exitEvent);
while ((cur = ellGet(&fList)) != NULL) {
VALGRIND_MEMPOOL_FREE(&fList, cur);
free(cur);
}
VALGRIND_DESTROY_MEMPOOL(&fList);
}
static void twdInitOnce(void *arg)
@@ -142,6 +149,8 @@ static void twdInitOnce(void *arg)
tLock = epicsMutexMustCreate();
mLock = epicsMutexMustCreate();
fLock = epicsMutexMustCreate();
ellInit(&fList);
VALGRIND_CREATE_MEMPOOL(&fList, 0, 0);
twdCtl = twdctlRun;
loopEvent = epicsEventMustCreate(epicsEventEmpty);
@@ -388,14 +397,16 @@ static union twdNode *newNode(void)
union twdNode *pn;
epicsMutexMustLock(fLock);
pn = (union twdNode *)ellFirst(&fList);
pn = (union twdNode *)ellGet(&fList);
if (pn) {
ellDelete(&fList, (void *)pn);
epicsMutexUnlock(fLock);
return pn;
VALGRIND_MEMPOOL_FREE(&fList, pn);
}
epicsMutexUnlock(fLock);
return calloc(1, sizeof(union twdNode));
if (!pn)
pn = calloc(1, sizeof(union twdNode));
if (pn)
VALGRIND_MEMPOOL_ALLOC(&fList, pn, sizeof(*pn));
return pn;
}
static union twdNode *allocNode(void)
@@ -411,6 +422,8 @@ static union twdNode *allocNode(void)
static void freeNode(union twdNode *pn)
{
VALGRIND_MEMPOOL_FREE(&fList, pn);
VALGRIND_MEMPOOL_ALLOC(&fList, pn, sizeof(ELLNODE));
epicsMutexMustLock(fLock);
ellAdd(&fList, (void *)pn);
epicsMutexUnlock(fLock);

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,7 @@
#include <db_field_log.h>
#include <dbLock.h>
#include <recSup.h>
#include <epicsExit.h>
#include <special.h>
#include <chfPlugin.h>
#include <epicsExport.h>
@@ -200,6 +201,11 @@ static chfPluginIf pif = {
NULL /* channel_close */
};
static void arrShutdown(void* ignore)
{
freeListCleanup(myStructFreeList);
}
static void arrInitialize(void)
{
static int firstTime = 1;
@@ -211,6 +217,7 @@ static void arrInitialize(void)
freeListInitPvt(&myStructFreeList, sizeof(myStruct), 64);
chfPluginRegister("arr", &pif, opts);
epicsAtExit(arrShutdown, NULL);
}
epicsExportRegistrar(arrInitialize);

View File

@@ -18,6 +18,7 @@
#include <dbConvertFast.h>
#include <chfPlugin.h>
#include <recGbl.h>
#include <epicsExit.h>
#include <db_field_log.h>
#include <epicsExport.h>
@@ -121,6 +122,11 @@ static chfPluginIf pif = {
NULL /* channel_close */
};
static void dbndShutdown(void* ignore)
{
freeListCleanup(myStructFreeList);
}
static void dbndInitialize(void)
{
static int firstTime = 1;
@@ -132,6 +138,7 @@ static void dbndInitialize(void)
freeListInitPvt(&myStructFreeList, sizeof(myStruct), 64);
chfPluginRegister("dbnd", &pif, opts);
epicsAtExit(dbndShutdown, NULL);
}
epicsExportRegistrar(dbndInitialize);

View File

@@ -16,6 +16,7 @@
#include "db_field_log.h"
#include "chfPlugin.h"
#include "dbState.h"
#include "epicsExit.h"
#include "epicsAssert.h"
#include "epicsExport.h"
@@ -174,6 +175,11 @@ static chfPluginIf pif = {
NULL /* channel_close */
};
static void syncShutdown(void* ignore)
{
freeListCleanup(myStructFreeList);
}
static void syncInitialize(void)
{
static int firstTime = 1;
@@ -185,6 +191,7 @@ static void syncInitialize(void)
freeListInitPvt(&myStructFreeList, sizeof(myStruct), 64);
chfPluginRegister("sync", &pif, opts);
epicsAtExit(syncShutdown, NULL);
}
epicsExportRegistrar(syncInitialize);