/* debug.c * * This file proides debug and run time error analysis support. Some of the * settings are very performance intense and my be turned off during a release * build. * * File begun on 2008-01-22 by RGerhards * * There is some in-depth documentation available in doc/dev_queue.html * (and in the web doc set on http://www.rsyslog.com/doc). Be sure to read it * if you are getting aquainted to the object. * * Copyright 2008 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Rsyslog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rsyslog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Rsyslog. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. */ #include "config.h" /* autotools! */ #include #include #include #include #include #include #include #include "rsyslog.h" #include "debug.h" /* static data (some time to be replaced) */ int Debug; /* debug flag - read-only after startup */ int debugging_on = 0; /* read-only, except on sig USR1 */ /* handler for SIGSEGV - MUST terminiate the app, but does so in a somewhat * more meaningful way. * rgerhards, 2008-01-22 */ void sigsegvHdlr(int signum) { struct sigaction sigAct; char *signame; if(signum == SIGSEGV) { signame = " (SIGSEGV)"; } else { signame = ""; } fprintf(stderr, "Signal %d%s occured, execution must be terminated %d.\n", signum, signame, SIGSEGV); fflush(stderr); /* re-instantiate original handler ... */ memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = SIG_DFL; sigaction(SIGSEGV, &sigAct, NULL); /* and call it */ int i= raise(signum); printf("raise returns %d, errno %d: %s\n", i, errno, strerror(errno)); /* we should never arrive here - but we provide some code just in case... */ fprintf(stderr, "sigsegvHdlr: oops, returned from raise(), doing exit(), something really wrong...\n"); exit(1); } /* print some debug output */ void dbgprintf(char *fmt, ...) { static pthread_t ptLastThrdID = 0; static int bWasNL = 0; va_list ap; if ( !(Debug && debugging_on) ) return; /* 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(stdout, "\n"); bWasNL = 1; } ptLastThrdID = pthread_self(); } if(bWasNL) { fprintf(stdout, "%8.8x: ", (unsigned int) pthread_self()); //fprintf(stderr, "%8.8x: ", (unsigned int) pthread_self()); } bWasNL = (*(fmt + strlen(fmt) - 1) == '\n') ? 1 : 0; va_start(ap, fmt); vfprintf(stdout, fmt, ap); //vfprintf(stderr, fmt, ap); va_end(ap); //fflush(stderr); fflush(stdout); return; } /* */ /* * vi:set ai: */