435 lines
12 KiB
C
435 lines
12 KiB
C
|
|
/************************************************************************/
|
||
|
|
/* SISCO SOFTWARE MODULE HEADER *****************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* (c) Copyright Systems Integration Specialists Company, Inc., */
|
||
|
|
/* 1993-2007, All Rights Reserved */
|
||
|
|
/* */
|
||
|
|
/* MODULE NAME : slogmem.c */
|
||
|
|
/* PRODUCT(S) : SLOG */
|
||
|
|
/* */
|
||
|
|
/* MODULE DESCRIPTION : */
|
||
|
|
/* */
|
||
|
|
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
|
||
|
|
/* */
|
||
|
|
/* MODIFICATION LOG : */
|
||
|
|
/* Date Who Rev Comments */
|
||
|
|
/* -------- --- ------ ------------------------------------------- */
|
||
|
|
/* 01/15/07 EJV 16 Chg S_LOCK_RESOURCES to S_LOCK_UTIL_RESOURCES*/
|
||
|
|
/* 07/13/05 JRB 15 slogGetMemMsg: skip timestamp on continuation*/
|
||
|
|
/* logs & indent 4 chars; indent hex logs. */
|
||
|
|
/* getMsgBuffer: make size based on max msg. */
|
||
|
|
/* 02/25/05 MDE 14 Added \n */
|
||
|
|
/* 01/10/05 MDE 13 Cleanup dump a bit */
|
||
|
|
/* 07/09/04 EJV 12 All systems: one time/date format in slog hdr*/
|
||
|
|
/* 03/12/04 GLB 11 Removed "thisFileName" */
|
||
|
|
/* 02/17/03 JRB 10 Del system includes (using sysincs.h). */
|
||
|
|
/* 05/24/01 JRB 09 Chg chk_calloc to calloc. This always compiled*/
|
||
|
|
/* with !DEBUG_SISCO, screws up link. */
|
||
|
|
/* 10/13/00 EJV 08 Moved glbsem.h below sysincs.h. */
|
||
|
|
/* 09/13/99 MDE 07 Added SD_CONST modifiers */
|
||
|
|
/* 02/09/99 DSF 06 Thread-safe slogMem () */
|
||
|
|
/* Remove extraneous newline in slogMemDump() */
|
||
|
|
/* 10/23/98 MDE 05 No blank line bet. logs if LOG_NO_HEADER_CR */
|
||
|
|
/* 10/16/98 DSF 04 Spelling */
|
||
|
|
/* 10/08/98 MDE 03 Migrated to updated SLOG interface */
|
||
|
|
/* 06/15/98 MDE 02 Changes to allow compile under C++ */
|
||
|
|
/* 09/18/97 DSF 01 In slogMemInit (), clear chk_debug_en before */
|
||
|
|
/* calling chk_calloc () and restore it after. */
|
||
|
|
/* 04/02/97 DTL 7.00 MMSEASE 7.0 release. See MODL70.DOC for */
|
||
|
|
/* history. */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
#include "glbtypes.h"
|
||
|
|
#include "sysincs.h"
|
||
|
|
#include "glbsem.h"
|
||
|
|
#include "mem_chk.h"
|
||
|
|
#include "slog.h"
|
||
|
|
#include "qmem.h"
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* Some mysterious looking function pointers */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID *(*slogAllocBuf) (ST_INT size) = qMemAlloc;
|
||
|
|
ST_VOID (*slogFreeBuf) (ST_VOID *buf) = qMemFree;
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* slogMem */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID slogMem (LOG_CTRL *lc,
|
||
|
|
SD_CONST ST_INT logType,
|
||
|
|
SD_CONST ST_CHAR *SD_CONST logTypeStr,
|
||
|
|
SD_CONST ST_CHAR *SD_CONST sourceFile,
|
||
|
|
SD_CONST ST_INT lineNum,
|
||
|
|
ST_INT bufLen, SD_CONST ST_CHAR *buf)
|
||
|
|
{
|
||
|
|
LOGMEM_ITEM *thisItem;
|
||
|
|
MEM_LOG_CTRL *mc;
|
||
|
|
|
||
|
|
S_GS_INIT ();
|
||
|
|
S_LOCK_UTIL_RESOURCES ();
|
||
|
|
|
||
|
|
/* get pointer to memory control structure */
|
||
|
|
|
||
|
|
mc = &lc->mc;
|
||
|
|
|
||
|
|
/* Check for initialization */
|
||
|
|
|
||
|
|
if (!(mc->state & MEM_STATE_INIT))
|
||
|
|
{
|
||
|
|
slogMemInit (lc);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Get pointer to the destination item and reset the 'next put' index */
|
||
|
|
|
||
|
|
thisItem = &mc->item[mc->nextPut];
|
||
|
|
|
||
|
|
mc->nextPut++;
|
||
|
|
if (mc->nextPut >= mc->maxItems) /* check for wraparound */
|
||
|
|
{
|
||
|
|
mc->nextPut = 0;
|
||
|
|
|
||
|
|
/* Check for autodump && clean */
|
||
|
|
|
||
|
|
if (mc->ctrl & MEM_CTRL_AUTODUMP_EN)
|
||
|
|
{
|
||
|
|
slogDumpMem (lc); /* Dump memory to log file */
|
||
|
|
slogResetMem (lc); /* Delete all contents */
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Check to see if we need to free the string buffer */
|
||
|
|
|
||
|
|
if (thisItem->flags & LMF_USED)
|
||
|
|
{
|
||
|
|
(*slogFreeBuf) (thisItem->string);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Set flags for this item */
|
||
|
|
|
||
|
|
if (mc->ctrl & MEM_CTRL_MSG_HDR_EN)
|
||
|
|
{
|
||
|
|
thisItem->flags = LMF_HEADER | LMF_USED;
|
||
|
|
thisItem->sourceFile = sourceFile; /* save source information */
|
||
|
|
thisItem->lineNum = lineNum;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
thisItem->flags = LMF_USED;
|
||
|
|
|
||
|
|
/* If this is a HEX log, remember that it is */
|
||
|
|
|
||
|
|
if (mc->ctrl & MEM_CTRL_HEX_LOG)
|
||
|
|
{
|
||
|
|
thisItem->flags |= LMF_HEX;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Save the log type information */
|
||
|
|
|
||
|
|
thisItem->logType = logType;
|
||
|
|
thisItem->logTypeStr = logTypeStr;
|
||
|
|
|
||
|
|
/* If time stamping is enabled, need to save the time */
|
||
|
|
|
||
|
|
if (lc->logCtrl & LOG_TIME_EN)
|
||
|
|
strcpy (thisItem->slogTimeText, slogTimeText);
|
||
|
|
|
||
|
|
/* Limit the string size (bufLen includes the null) */
|
||
|
|
|
||
|
|
if (bufLen > SLOG_MEM_BUF_SIZE)
|
||
|
|
{
|
||
|
|
bufLen = SLOG_MEM_BUF_SIZE;
|
||
|
|
thisItem->string = (ST_CHAR *) (*slogAllocBuf) (bufLen+1);
|
||
|
|
strncpy (thisItem->string, buf, SLOG_MEM_BUF_SIZE -1);
|
||
|
|
thisItem->string[SLOG_MEM_BUF_SIZE-1] = 0;
|
||
|
|
}
|
||
|
|
else /* no buffer size adjustments req'd */
|
||
|
|
{
|
||
|
|
thisItem->string = (ST_CHAR *) (*slogAllocBuf) (bufLen+1);
|
||
|
|
strcpy (thisItem->string, buf);
|
||
|
|
}
|
||
|
|
|
||
|
|
S_UNLOCK_UTIL_RESOURCES ();
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* slogDumpMem */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID slogDumpMem (LOG_CTRL *lc)
|
||
|
|
{
|
||
|
|
LOGMEM_ITEM *item;
|
||
|
|
LOGMEM_ITEM *tooFar;
|
||
|
|
ST_INT count;
|
||
|
|
FILE *fh;
|
||
|
|
time_t t;
|
||
|
|
ST_CHAR fname[SLOG_MAX_FNAME + 1];
|
||
|
|
MEM_LOG_CTRL *mc;
|
||
|
|
ST_INT i;
|
||
|
|
|
||
|
|
S_GS_INIT ();
|
||
|
|
S_LOCK_UTIL_RESOURCES ();
|
||
|
|
|
||
|
|
/* get pointer to memory control structure */
|
||
|
|
|
||
|
|
mc = &lc->mc;
|
||
|
|
|
||
|
|
if (!(mc->state & MEM_STATE_INIT))
|
||
|
|
{
|
||
|
|
S_UNLOCK_UTIL_RESOURCES ();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
fh = fopen(mc->dumpFileName, "a+");
|
||
|
|
if (!fh)
|
||
|
|
fh = fopen(mc->dumpFileName, "w+");
|
||
|
|
|
||
|
|
if (fh)
|
||
|
|
{
|
||
|
|
|
||
|
|
/* Print the dump header */
|
||
|
|
|
||
|
|
t = time(NULL);
|
||
|
|
fprintf (fh,"\n\n***********************************************************");
|
||
|
|
fprintf (fh,"\n MEMORY LOG LIST %s", ctime(&t));
|
||
|
|
fprintf (fh,"***********************************************************");
|
||
|
|
|
||
|
|
count = mc->maxItems; /* just in case, for loop escape */
|
||
|
|
|
||
|
|
/* start at the last logged item, which would be 'next put' */
|
||
|
|
/* if the list has wrapped, otherwise somewhere down the list */
|
||
|
|
|
||
|
|
item = &mc->item[mc->nextPut]; /* Item to log */
|
||
|
|
tooFar = &mc->item[mc->maxItems]; /* 1 past end of array */
|
||
|
|
|
||
|
|
for (i = 0; i < count; ++i,++item) /* for each possible item */
|
||
|
|
{
|
||
|
|
if (item >= tooFar) /* check for wrap */
|
||
|
|
item = mc->item; /* go to top */
|
||
|
|
|
||
|
|
if (item->flags & LMF_USED) /* if used .. */
|
||
|
|
{
|
||
|
|
if (item->flags & LMF_HEADER)
|
||
|
|
{ /* header info is to be used */
|
||
|
|
if (!(lc->logCtrl & LOG_NO_HEADER_CR))
|
||
|
|
fprintf (fh,"\n");
|
||
|
|
|
||
|
|
if (item->logType != SLOG_CONT)
|
||
|
|
{
|
||
|
|
if (lc->logCtrl & LOG_TIME_EN) /* user wants time stamp */
|
||
|
|
fprintf (fh,"\n%s ", item->slogTimeText);
|
||
|
|
|
||
|
|
if (!(lc->logCtrl & LOG_LOGTYPE_SUPPRESS))
|
||
|
|
{
|
||
|
|
if (item->logTypeStr != NULL)
|
||
|
|
fprintf (fh,"%s ", item->logTypeStr);
|
||
|
|
else
|
||
|
|
fprintf (fh,"LogType:% 2d ", item->logType);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (item->sourceFile && !(lc->logCtrl & LOG_FILENAME_SUPPRESS))
|
||
|
|
{
|
||
|
|
slogTrimFileName (fname,item->sourceFile);
|
||
|
|
fprintf (fh,"(%s %d) ", fname, item->lineNum);
|
||
|
|
}
|
||
|
|
if (!(lc->logCtrl & LOG_NO_HEADER_CR))
|
||
|
|
fprintf (fh,"\n ");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (item->logType == SLOG_CONT)
|
||
|
|
fprintf (fh," ");
|
||
|
|
|
||
|
|
fprintf(fh,"%s",item->string);
|
||
|
|
} /* end if used */
|
||
|
|
} /* end for each possible item */
|
||
|
|
fclose(fh);
|
||
|
|
}
|
||
|
|
S_UNLOCK_UTIL_RESOURCES ();
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* slogResetMem */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID slogResetMem (LOG_CTRL *lc)
|
||
|
|
{
|
||
|
|
LOGMEM_ITEM *item;
|
||
|
|
ST_INT i;
|
||
|
|
MEM_LOG_CTRL *mc;
|
||
|
|
|
||
|
|
S_GS_INIT ();
|
||
|
|
S_LOCK_UTIL_RESOURCES ();
|
||
|
|
|
||
|
|
/* get pointer to memory control structure */
|
||
|
|
mc = &lc->mc;
|
||
|
|
|
||
|
|
if (!(mc->state & MEM_STATE_INIT))
|
||
|
|
return;
|
||
|
|
|
||
|
|
/* just go through the list, clear the used flag && free the str buf */
|
||
|
|
|
||
|
|
item = mc->item;
|
||
|
|
for (i = 0; i < mc->maxItems; ++i, ++item)
|
||
|
|
{
|
||
|
|
if (item->flags & LMF_USED)
|
||
|
|
{
|
||
|
|
item->flags &= ~LMF_USED;
|
||
|
|
(*slogFreeBuf) (item->string);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
mc->nextPut = 0;
|
||
|
|
S_UNLOCK_UTIL_RESOURCES ();
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* slogMemInit */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
#define SLOG_MAX_ITEMS (0xFF00/sizeof(LOGMEM_ITEM))
|
||
|
|
|
||
|
|
ST_VOID slogMemInit (LOG_CTRL *lc)
|
||
|
|
{
|
||
|
|
MEM_LOG_CTRL *mc;
|
||
|
|
ST_UINT save_debug_en;
|
||
|
|
|
||
|
|
mc = &lc->mc;
|
||
|
|
if (!mc->maxItems)
|
||
|
|
{
|
||
|
|
fprintf (stderr,"\n Memory Logging Problem - 0 Items");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mc->maxItems > SLOG_MAX_ITEMS)
|
||
|
|
{
|
||
|
|
fprintf (stderr,"\n Memory Logging Problem - Too Many Items");
|
||
|
|
mc->maxItems = SLOG_MAX_ITEMS;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (qMemInit (mc->maxItems))
|
||
|
|
{
|
||
|
|
fprintf (stderr,"\n QMEM Initialization Problem");
|
||
|
|
mc->maxItems = 0;
|
||
|
|
lc->logCtrl &= ~LOG_MEM_EN;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* Allocate a zero'd memory block for the item control list */
|
||
|
|
save_debug_en = chk_debug_en;
|
||
|
|
chk_debug_en = 0;
|
||
|
|
mc->item =
|
||
|
|
(LOGMEM_ITEM *) calloc (mc->maxItems, sizeof (LOGMEM_ITEM));
|
||
|
|
chk_debug_en = save_debug_en;
|
||
|
|
}
|
||
|
|
|
||
|
|
mc->state |= MEM_STATE_INIT;
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* slogGetMemMsg */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
/* Need buffer big enough for max msg plus extra space for timestamp. */
|
||
|
|
/* 50 should leave plenty of safety margin. */
|
||
|
|
static ST_CHAR getMsgBuffer[SLOG_MEM_BUF_SIZE + 50];
|
||
|
|
|
||
|
|
ST_CHAR *slogGetMemMsg (LOG_CTRL *lc, SD_CONST ST_INT msgNum)
|
||
|
|
{
|
||
|
|
ST_INT i;
|
||
|
|
MEM_LOG_CTRL *mc;
|
||
|
|
ST_INT index;
|
||
|
|
|
||
|
|
S_GS_INIT ();
|
||
|
|
S_LOCK_UTIL_RESOURCES ();
|
||
|
|
|
||
|
|
/* get pointer to memory control structure */
|
||
|
|
|
||
|
|
mc = &lc->mc;
|
||
|
|
if (!(mc->state & MEM_STATE_INIT) || msgNum > mc->maxItems)
|
||
|
|
{
|
||
|
|
S_UNLOCK_UTIL_RESOURCES ();
|
||
|
|
return (NULL);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* FInd the start index in the item array */
|
||
|
|
|
||
|
|
index = mc->nextPut; /* if wrapped, next put is oldest item */
|
||
|
|
if (!(mc->item[index].flags & LMF_USED)) /* but if not wrapped */
|
||
|
|
index = 0; /* oldest is item 0 */
|
||
|
|
|
||
|
|
/* Find the 'msgNum' item index (msgNum == 0 means oldest item) */
|
||
|
|
|
||
|
|
for (i = 0; i < msgNum; ++i)
|
||
|
|
{
|
||
|
|
++index;
|
||
|
|
if (index >= mc->maxItems) /* check for wraparound */
|
||
|
|
index = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((mc->item[index].flags & LMF_USED)) /* if used ... */
|
||
|
|
{
|
||
|
|
/* too easy! return (mc->item[index].string); */
|
||
|
|
|
||
|
|
if (lc->logCtrl & LOG_TIME_EN)
|
||
|
|
{
|
||
|
|
if (mc->item[index].flags & LMF_HEADER)
|
||
|
|
{
|
||
|
|
if (mc->item[index].logType == SLOG_CONT)
|
||
|
|
sprintf (getMsgBuffer," %s", mc->item[index].string); /* indent 4 char*/
|
||
|
|
else
|
||
|
|
sprintf (getMsgBuffer,"%s: %s", &mc->item[index].slogTimeText[11],
|
||
|
|
mc->item[index].string);
|
||
|
|
}
|
||
|
|
else if (mc->item[index].flags & LMF_HEX)
|
||
|
|
sprintf (getMsgBuffer," %s", mc->item[index].string); /* indent 4 char*/
|
||
|
|
else
|
||
|
|
sprintf (getMsgBuffer," %s", mc->item[index].string);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (mc->item[index].logType == SLOG_CONT)
|
||
|
|
sprintf (getMsgBuffer," %s", mc->item[index].string); /* indent 4 char*/
|
||
|
|
else
|
||
|
|
sprintf (getMsgBuffer,"%s", mc->item[index].string);
|
||
|
|
}
|
||
|
|
|
||
|
|
S_UNLOCK_UTIL_RESOURCES ();
|
||
|
|
return (getMsgBuffer);
|
||
|
|
}
|
||
|
|
|
||
|
|
S_UNLOCK_UTIL_RESOURCES ();
|
||
|
|
return (NULL);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* slogGetMemCount */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_INT slogGetMemCount (LOG_CTRL *lc)
|
||
|
|
{
|
||
|
|
MEM_LOG_CTRL *mc;
|
||
|
|
|
||
|
|
S_GS_INIT ();
|
||
|
|
S_LOCK_UTIL_RESOURCES ();
|
||
|
|
|
||
|
|
/* get pointer to memory control structure */
|
||
|
|
|
||
|
|
mc = &lc->mc;
|
||
|
|
if (!(mc->state & MEM_STATE_INIT))
|
||
|
|
{
|
||
|
|
S_UNLOCK_UTIL_RESOURCES ();
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mc->item[mc->nextPut].flags & LMF_USED) /* if wrapped, */
|
||
|
|
{
|
||
|
|
S_UNLOCK_UTIL_RESOURCES ();
|
||
|
|
return (mc->maxItems);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
S_UNLOCK_UTIL_RESOURCES ();
|
||
|
|
return (mc->nextPut);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|