cmMem.c : Added string tables for 'filename' and 'function name' strings

in the cmMmRecd_t record.

Previously the 'fileNameStr' and 'funcNameStr' were assumed to be stored
in static memory and therefore did not require duplication.  If the
strings however originated in a dynamic library then the string pointer
would be invalid after the library is unloaded.  Accessing these fields
would then result in a crash.
This commit is contained in:
kpl 2013-10-08 16:43:38 -07:00
parent fb509b10c7
commit 42a9f19166

59
cmMem.c
View File

@ -52,12 +52,18 @@ typedef struct cmMmRecd_str
void* dataPtr; // dataPtr may be NULL if the assoc'd alloc request was for 0 bytes. void* dataPtr; // dataPtr may be NULL if the assoc'd alloc request was for 0 bytes.
unsigned dataByteCnt; // data area bytes on original allocation unsigned dataByteCnt; // data area bytes on original allocation
unsigned fileLine; unsigned fileLine;
const char* fileNameStr; char* fileNameStr;
const char* funcNameStr; char* funcNameStr;
unsigned flags; unsigned flags;
struct cmMmRecd_str* linkPtr; struct cmMmRecd_str* linkPtr;
} cmMmRecd_t; } cmMmRecd_t;
typedef struct cmMmStr_str
{
struct cmMmStr_str* link;
char* str;
} cmMmStr_t;
typedef struct typedef struct
{ {
cmRpt_t* rpt; cmRpt_t* rpt;
@ -73,6 +79,8 @@ typedef struct
char freeChar; char freeChar;
char guardChar; char guardChar;
unsigned flags; unsigned flags;
cmMmStr_t* fnList;
cmMmStr_t* funcList;
} cmMm_t; } cmMm_t;
cmMmH_t cmMmNullHandle = { NULL }; cmMmH_t cmMmNullHandle = { NULL };
@ -380,6 +388,18 @@ cmMmRC_t cmMmInitialize(
return kOkMmRC; return kOkMmRC;
} }
void _cmMmFreeStrList( cmMmStr_t* cp )
{
while( cp!=NULL )
{
cmMmStr_t* np = cp->link;
free(cp->str);
free(cp);
cp = np;
}
}
cmMmRC_t cmMmFinalize( cmMmH_t* hp ) cmMmRC_t cmMmFinalize( cmMmH_t* hp )
{ {
cmMm_t* p; cmMm_t* p;
@ -404,6 +424,9 @@ cmMmRC_t cmMmFinalize( cmMmH_t* hp )
rp = tp; rp = tp;
} }
_cmMmFreeStrList(p->fnList);
_cmMmFreeStrList(p->funcList);
free(p); free(p);
hp->h = NULL; hp->h = NULL;
@ -431,6 +454,32 @@ unsigned cmMmInitializeFlags( cmMmH_t h )
bool cmMmIsValid( cmMmH_t h ) bool cmMmIsValid( cmMmH_t h )
{ return h.h != NULL; } { return h.h != NULL; }
// Allocate and/or return a pointer to a stored string.
char* _cmMmAllocStr( cmMmStr_t** listPtrPtr, const char* str )
{
if( str == NULL )
str = "";
cmMmStr_t* lp = *listPtrPtr; // get ptr to first recd in list
cmMmStr_t* cp = lp; // init current ptr
// find 'str' in the list
for(; cp!=NULL; cp=cp->link)
if( strcmp(cp->str,str) == 0 )
break;
// 'str' was not found - create a new string recd
if( cp == NULL )
{
cp = calloc(1,sizeof(cmMmStr_t));
cp->str = strdup(str);
cp->link = lp;
*listPtrPtr = cp;
}
return cp->str;
}
void* cmMmAllocate( void* cmMmAllocate(
cmMmH_t h, cmMmH_t h,
void* orgDataPtr, void* orgDataPtr,
@ -483,8 +532,8 @@ void* cmMmAllocate(
rp->dataPtr = ndp; rp->dataPtr = ndp;
rp->dataByteCnt = newByteCnt; rp->dataByteCnt = newByteCnt;
rp->fileLine = fileLine; rp->fileLine = fileLine;
rp->fileNameStr = fileName; rp->fileNameStr = _cmMmAllocStr( &p->fnList, fileName );
rp->funcNameStr = funcName; rp->funcNameStr = _cmMmAllocStr( &p->funcList, funcName);
rp->flags = 0; rp->flags = 0;
rp->uniqueId = p->nextId; rp->uniqueId = p->nextId;
@ -587,7 +636,7 @@ cmMmRC_t _cmMmRecdPrint( cmMm_t* p, cmMmRecd_t* rp, cmMmRC_t rc )
lbl = "Unknown Status "; lbl = "Unknown Status ";
} }
cmRptPrintf(p->err.rpt,"%s id:%5i data:%p : data:%5i prefix:%5i total:%5i base:%p : %5i %s %s\n", cmRptPrintf(p->err.rpt,"%s id:%5i data:%p : data:%5i prefix:%5i total:%5i base:%p : line=%5i %s %s\n",
lbl,rp->uniqueId,rp->dataPtr, lbl,rp->uniqueId,rp->dataPtr,
_cmMmDataToByteCnt(dp,gbc), _cmMmDataToByteCnt(dp,gbc),
_cmMmDataToPrefixCnt(dp,gbc), _cmMmDataToPrefixCnt(dp,gbc),