summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-01-29 10:23:10 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2008-01-29 10:23:10 +0000
commit19cad8b12fa34e05f903c1d55c77453be1bab431 (patch)
treea7f3a8c4ec25c1670530933aeea498330d3ab70a
parent33a8ec9855b7e7674ab2b1a6e4814b08652296de (diff)
downloadrsyslog-19cad8b12fa34e05f903c1d55c77453be1bab431.tar.gz
rsyslog-19cad8b12fa34e05f903c1d55c77453be1bab431.tar.xz
rsyslog-19cad8b12fa34e05f903c1d55c77453be1bab431.zip
implemented naming for all objects (mostly as a debug aid, but you never
know what else it will be good for)
-rw-r--r--debug.c87
-rw-r--r--debug.h4
-rw-r--r--msg.c2
-rw-r--r--obj-types.h19
-rw-r--r--obj.c62
-rw-r--r--obj.h6
-rw-r--r--queue.c11
-rw-r--r--syslogd.c13
-rw-r--r--wtp.c1
9 files changed, 169 insertions, 36 deletions
diff --git a/debug.c b/debug.c
index 4605eec8..82ed2442 100644
--- a/debug.c
+++ b/debug.c
@@ -48,6 +48,7 @@
#include "rsyslog.h"
#include "debug.h"
+#include "obj.h"
/* forward definitions */
static void dbgGetThrdName(char *pszBuf, size_t lenBuf, pthread_t thrd, int bIncludeNumID);
@@ -684,7 +685,91 @@ sigsegvHdlr(int signum)
}
-/* print some debug output */
+/* print some debug output when an object is given
+ * This is mostly a copy of dbgprintf, but I do not know how to combine it
+ * into a single function as we have variable arguments and I don't know how to call
+ * from one vararg function into another. I don't dig in this, it is OK for the
+ * time being. -- rgerhards, 2008-01-29
+ */
+void
+dbgoprint(obj_t *pObj, char *fmt, ...)
+{
+ static pthread_t ptLastThrdID = 0;
+ static int bWasNL = 0;
+ va_list ap;
+ static char pszThrdName[64]; /* 64 is to be on the safe side, anything over 20 is bad... */
+ static char pszWriteBuf[1024];
+ size_t lenWriteBuf;
+ struct timespec t;
+
+ if(!(Debug && debugging_on))
+ return;
+
+ pthread_mutex_lock(&mutdbgprintf);
+ pthread_cleanup_push(dbgMutexCancelCleanupHdlr, &mutdbgprintf);
+
+ /* The bWasNL handler does not really work. It works if no thread
+ * switching occurs during non-NL messages. Else, things are messed
+ * up. Anyhow, it works well enough to provide useful help during
+ * getting this up and running. It is questionable if the extra effort
+ * is worth fixing it, giving the limited appliability.
+ * rgerhards, 2005-10-25
+ * I have decided that it is not worth fixing it - especially as it works
+ * pretty well.
+ * rgerhards, 2007-06-15
+ */
+ if(ptLastThrdID != pthread_self()) {
+ if(!bWasNL) {
+ fprintf(stddbg, "\n");
+ if(altdbg != NULL) fprintf(altdbg, "\n");
+ bWasNL = 1;
+ }
+ ptLastThrdID = pthread_self();
+ }
+
+ /* do not cache the thread name, as the caller might have changed it
+ * TODO: optimized, invalidate cache when new name is set
+ */
+ dbgGetThrdName(pszThrdName, sizeof(pszThrdName), ptLastThrdID, 0);
+
+ if(bWasNL) {
+ if(bPrintTime) {
+ clock_gettime(CLOCK_REALTIME, &t);
+ fprintf(stddbg, "%4.4ld.%9.9ld:", t.tv_sec % 10000, t.tv_nsec);
+ if(altdbg != NULL) fprintf(altdbg, "%4.4ld.%9.9ld:", t.tv_sec % 10000, t.tv_nsec);
+ }
+ fprintf(stddbg, "%s: ", pszThrdName);
+ if(altdbg != NULL) fprintf(altdbg, "%s: ", pszThrdName);
+ /* print object name header if we have an object */
+ if(pObj != NULL) {
+ fprintf(stddbg, "%s: ", objGetName(pObj));
+ if(altdbg != NULL) fprintf(altdbg, "%s: ", objGetName(pObj));
+ }
+ }
+ bWasNL = (*(fmt + strlen(fmt) - 1) == '\n') ? 1 : 0;
+ va_start(ap, fmt);
+ lenWriteBuf = vsnprintf(pszWriteBuf, sizeof(pszWriteBuf), fmt, ap);
+ if(lenWriteBuf >= sizeof(pszWriteBuf)) {
+ /* if our buffer was too small, we simply truncate. TODO: maybe something better? */
+ lenWriteBuf--;
+ }
+ va_end(ap);
+ /*
+ fprintf(stddbg, "%s", pszWriteBuf);
+ if(altdbg != NULL) fprintf(altdbg, "%s", pszWriteBuf);
+ */
+ fwrite(pszWriteBuf, lenWriteBuf, 1, stddbg);
+ if(altdbg != NULL) fwrite(pszWriteBuf, lenWriteBuf, 1, altdbg);
+
+ fflush(stddbg);
+ if(altdbg != NULL) fflush(altdbg);
+ pthread_cleanup_pop(1);
+}
+
+
+/* print some debug output when no object is given
+ * WARNING: duplicate code, see dbgoprin above!
+ */
void
dbgprintf(char *fmt, ...)
{
diff --git a/debug.h b/debug.h
index 9c28eca1..df8c3138 100644
--- a/debug.h
+++ b/debug.h
@@ -26,6 +26,7 @@
#define DEBUG_H_INCLUDED
#include <pthread.h>
+#include "obj-types.h"
/* external static data elements (some time to be replaced) */
extern int Debug; /* debug flag - read-only after startup */
@@ -84,7 +85,8 @@ typedef struct dbgCallStack_s {
rsRetVal dbgClassInit(void);
rsRetVal dbgClassExit(void);
void sigsegvHdlr(int signum);
-void dbgprintf(char *fmt, ...) __attribute__((format(printf,1, 2)));
+void dbgoprint(obj_t *pObj, char *fmt, ...) __attribute__((format(printf, 2, 3)));
+void dbgprintf(char *fmt, ...) __attribute__((format(printf, 1, 2)));
int dbgMutexLock(pthread_mutex_t *pmut, dbgFuncDB_t *pFuncD, int ln, int iStackPtr);
int dbgMutexUnlock(pthread_mutex_t *pmut, dbgFuncDB_t *pFuncD, int ln, int iStackPtr);
int dbgCondWait(pthread_cond_t *cond, pthread_mutex_t *pmut, dbgFuncDB_t *pFuncD, int ln, int iStackPtr);
diff --git a/msg.c b/msg.c
index 3bdc1f92..cc81c109 100644
--- a/msg.c
+++ b/msg.c
@@ -27,7 +27,6 @@
* A copy of the GPL can be found in the file "COPYING" in this distribution.
*/
#include "config.h"
-#include "rsyslog.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
@@ -36,6 +35,7 @@
#include <string.h>
#include <assert.h>
#include <ctype.h>
+#include "rsyslog.h"
#include "syslogd.h"
#include "srUtils.h"
#include "stringbuf.h"
diff --git a/obj-types.h b/obj-types.h
index 01842a83..bd0da73e 100644
--- a/obj-types.h
+++ b/obj-types.h
@@ -29,11 +29,7 @@
#define OBJ_TYPES_H_INCLUDED
#include "stringbuf.h"
-
-/* base object data, present in all objects */
-typedef struct objData_s {
- uchar *pName;
-} objData_t;
+#include "syslogd-types.h"
/* property types */
typedef enum { /* do NOT start at 0 to detect uninitialized types after calloc() */
@@ -90,23 +86,22 @@ typedef struct objInfo_s {
rsRetVal (*objMethods[OBJ_NUM_METHODS])();
} objInfo_t;
-/* TODO: move obj_t at front of struct */
+
typedef struct obj { /* the dummy struct that each derived class can be casted to */
objInfo_t *pObjInfo;
#ifndef NDEBUG /* this means if debug... */
- objData_t objData;
unsigned int iObjCooCKiE; /* must always be 0xBADEFEE for a valid object */
#endif
+ uchar *pszName; /* the name of *this* specific object instance */
} obj_t;
+
/* macros which must be gloablly-visible (because they are used during definition of
* other objects.
*/
#ifndef NDEBUG /* this means if debug... */
# define BEGINobjInstance \
- objInfo_t *pObjInfo; \
- objData_t objData; \
- unsigned int iObjCooCKiE; /* prevent name conflict, thus the strange name */
+ obj_t objData;
# define ISOBJ_assert(pObj) \
do { \
ASSERT((pObj) != NULL); \
@@ -115,11 +110,11 @@ typedef struct obj { /* the dummy struct that each derived class can be casted t
# define ISOBJ_TYPE_assert(pObj, objType) \
do { \
ASSERT(pObj != NULL); \
- ASSERT((unsigned) pObj->iObjCooCKiE == (unsigned) 0xBADEFEE); \
+ ASSERT((unsigned) ((obj_t*) (pObj))->iObjCooCKiE == (unsigned) 0xBADEFEE); \
ASSERT(objGetObjID(pObj) == OBJ##objType); \
} while(0);
#else /* non-debug mode, no checks but much faster */
-# define BEGINobjInstance objInfo_t *pObjInfo; objData_t objData;
+# define BEGINobjInstance objInfo_t *objData.pObjInfo; objData_t objData;
# define ISOBJ_TYPE_assert(pObj, objType)
# define ISOBJ_assert(pObj)
#endif
diff --git a/obj.c b/obj.c
index dfd3edd0..1559628b 100644
--- a/obj.c
+++ b/obj.c
@@ -1,3 +1,5 @@
+// TODO: we need to be called when the derived object is destructed!!!!
+
/* obj.c
*
* This file implements a generic object "class". All other classes can
@@ -146,7 +148,7 @@ static rsRetVal objSerializeHeader(strm_t *pStrm, obj_t *pObj, uchar *pszRecType
* the object back in
*/
CHKiRet(strmWriteChar(pStrm, ':'));
- CHKiRet(strmWrite(pStrm, objGetName(pObj), strlen((char*)objGetName(pObj))));
+ CHKiRet(strmWrite(pStrm, objGetClassName(pObj), strlen((char*)objGetClassName(pObj))));
/* record trailer */
CHKiRet(strmWriteChar(pStrm, ':'));
CHKiRet(strmWriteChar(pStrm, '\n'));
@@ -764,6 +766,64 @@ finalize_it:
/* --------------- end object serializiation / deserialization support --------------- */
+
+/* set the object (instance) name
+ * rgerhards, 2008-01-29
+ * TODO: change the naming to a rsCStr obj! (faster)
+ */
+rsRetVal
+objSetName(obj_t *pThis, uchar *pszName)
+{
+ DEFiRet;
+
+ if(pThis->pszName != NULL)
+ free(pThis->pszName);
+
+ pThis->pszName = (uchar*) strdup((char*) pszName);
+
+ if(pThis->pszName == NULL)
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* get the object (instance) name
+ * Note that we use a non-standard calling convention. Thus function must never
+ * fail, else we run into real big problems. So it must make sure that at least someting
+ * is returned.
+ * rgerhards, 2008-01-30
+ */
+uchar *
+objGetName(obj_t *pThis)
+{
+ uchar *ret;
+ uchar szName[128];
+
+ BEGINfunc
+ ISOBJ_assert(pThis);
+
+ if(pThis->pszName == NULL) {
+ snprintf((char*)szName, sizeof(szName)/sizeof(uchar), "%s %p", objGetClassName(pThis), pThis);
+ objSetName(pThis, szName);
+ /* looks strange, but we NEED to re-check because if there was an
+ * error in objSetName(), the pointer may still be NULL
+ */
+ if(pThis->pszName == NULL) {
+ ret = objGetClassName(pThis);
+ } else {
+ ret = pThis->pszName;
+ }
+ } else {
+ ret = pThis->pszName;
+ }
+
+ ENDfunc
+ return ret;
+}
+
+
/* register a classe's info pointer, so that we can reference it later, if needed to
* (e.g. for de-serialization support).
* rgerhards, 2008-01-07
diff --git a/obj.h b/obj.h
index 6b965e10..3eb3f194 100644
--- a/obj.h
+++ b/obj.h
@@ -66,13 +66,13 @@
#define objSerializePTR(strm, propName, propType) \
CHKiRet(objSerializeProp(strm, (uchar*) #propName, PROPTYPE_##propType, (void*) pThis->propName));
#define DEFobjStaticHelpers static objInfo_t *pObjInfoOBJ = NULL;
-#define objGetName(pThis) (((obj_t*) (pThis))->pObjInfo->pszName)
+#define objGetClassName(pThis) (((obj_t*) (pThis))->pObjInfo->pszName)
#define objGetObjID(pThis) (((obj_t*) (pThis))->pObjInfo->objID)
#define objGetVersion(pThis) (((obj_t*) (pThis))->pObjInfo->iObjVers)
/* the next macro MUST be called in Constructors: */
#ifndef NDEBUG /* this means if debug... */
# define objConstructSetObjInfo(pThis) \
- assert(pThis->pObjInfo == NULL); \
+ ASSERT(((obj_t*) (pThis))->pObjInfo == NULL); \
((obj_t*) (pThis))->pObjInfo = pObjInfoOBJ; \
((obj_t*) (pThis))->iObjCooCKiE = 0xBADEFEE
#else
@@ -95,6 +95,8 @@ rsRetVal objEndSerialize(strm_t *pStrm);
rsRetVal objRegisterObj(objID_t oID, objInfo_t *pInfo);
rsRetVal objDeserialize(void *ppObj, objID_t objTypeExpected, strm_t *pStrm, rsRetVal (*fFixup)(obj_t*,void*), void *pUsr);
rsRetVal objDeserializePropBag(obj_t *pObj, strm_t *pStrm);
+rsRetVal objSetName(obj_t *pThis, uchar *pszName);
+uchar * objGetName(obj_t *pThis);
PROTOTYPEObjClassInit(obj);
#endif /* #ifndef OBJ_H_INCLUDED */
diff --git a/queue.c b/queue.c
index 39c9639e..c617de75 100644
--- a/queue.c
+++ b/queue.c
@@ -1106,9 +1106,7 @@ rsRetVal queueConstruct(queue_t **ppThis, queueType_t qType, int iWorkerThreads,
}
finalize_it:
-RUNLOG_VAR("%x", pThis->iObjCooCKiE );
OBJCONSTRUCT_CHECK_SUCCESS_AND_CLEANUP
-RUNLOG_VAR("%x", pThis->iObjCooCKiE );
RETiRet;
}
@@ -1422,26 +1420,25 @@ rsRetVal queueStart(queue_t *pThis) /* this is the ConstructionFinalizer */
* influenced by properties which might have been set after queueConstruct ()
*/
if(pThis->pqParent == NULL) {
-dbgprintf("Queue %p: no parent, alloc mutex\n", pThis);
pThis->mut = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t));
pthread_mutex_init(pThis->mut, NULL);
} else {
/* child queue, we need to use parent's mutex */
+ dbgoprint((obj_t*) pThis, "I am a child\n");
pThis->mut = pThis->pqParent->mut;
-dbgprintf("Queue %p: I am child, use mutex %p\n", pThis, pThis->pqParent->mut);
}
pthread_mutex_init(&pThis->mutThrdMgmt, NULL);
pthread_cond_init (&pThis->condDAReady, NULL);
pthread_cond_init (&pThis->notFull, NULL);
pthread_cond_init (&pThis->notEmpty, NULL);
-dbgprintf("Queue %p: post mutexes, mut %p\n", pThis, pThis->mut);
/* call type-specific constructor */
CHKiRet(pThis->qConstruct(pThis)); /* this also sets bIsDA */
- dbgprintf("Queue 0x%lx: type %d, enq-only %d, disk assisted %d, maxFileSz %ld, qsize %d starting\n", queueGetID(pThis),
- pThis->qType, pThis->bEnqOnly, pThis->bIsDA, pThis->iMaxFileSize, pThis->iQueueSize);
+ dbgoprint((obj_t*) pThis, "type %d, enq-only %d, disk assisted %d, maxFileSz %ld, qsize %d, child %d starting\n",
+ pThis->qType, pThis->bEnqOnly, pThis->bIsDA, pThis->iMaxFileSize,
+ pThis->iQueueSize, pThis->pqParent == NULL ? 0 : 1);
if(pThis->qType == QUEUETYPE_DIRECT)
FINALIZE; /* with direct queues, we are already finished... */
diff --git a/syslogd.c b/syslogd.c
index a1e89530..574100a5 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -1661,16 +1661,6 @@ int shouldProcessThisMessage(selector_t *f, msg_t *pMsg)
}
-/* cancellation cleanup handler - frees the action mutex
- * rgerhards, 2008-01-14
- */
-static void callActionMutClean(void *arg)
-{
- assert(arg != NULL);
- pthread_mutex_unlock((pthread_mutex_t*) arg);
-}
-
-
/* helper to processMsg(), used to call the configured actions. It is
* executed from within llExecFunc() of the action list.
* rgerhards, 2007-08-02
@@ -3211,6 +3201,9 @@ init(void)
fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet);
exit(1);
}
+ /* name our main queue object (it's not fatal if it fails...) */
+ objSetName((obj_t*) pMsgQueue, (uchar*) "main queue");
+
/* ... set some properties ... */
# define setQPROP(func, directive, data) \
CHKiRet_Hdlr(func(pMsgQueue, data)) { \
diff --git a/wtp.c b/wtp.c
index 63507279..69ca353b 100644
--- a/wtp.c
+++ b/wtp.c
@@ -616,7 +616,6 @@ wtpSetDbgHdr(wtp_t *pThis, uchar *pszMsg, size_t lenMsg)
{
DEFiRet;
-dbgprintf("objID: %d\n", pThis->pObjInfo->objID);
ISOBJ_TYPE_assert(pThis, wtp);
assert(pszMsg != NULL);