/* * Debugging checkpoints * * Copyright 2008-2009 Nicolas Bernard * All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #include #include #include #include #include #include "dbgpoint.h" #include "debug.h" #ifndef NDEBUG unsigned int _dbgpointmax = 30; struct dbgpoint_data { long long where; struct timeval tv; }; struct dbgpoint_data dbgpoints[__DBGPOINTMAX]; static void dumpdbgpoints(void) { for (int i = 0; i < __DBGPOINTMAX; i++) { struct timeval tv_tmp; timersub(&dbgpoints[i].tv, &dbgpoints[0].tv, &tv_tmp); debug("%lld: %lu.%06lu -> %lu.%06lu", dbgpoints[i].where, dbgpoints[i].tv.tv_sec, dbgpoints[i].tv.tv_usec, tv_tmp.tv_sec, tv_tmp.tv_usec); } } #endif /* ! NDEBUG */ void dumponsignal(int sig) { sigset_t samask, osamask; int err = sigfillset(&samask); assert(err == 0); err = sigprocmask(SIG_BLOCK, &samask, &osamask); assert(err == 0); #ifndef NDEBUG dumpdbgpoints(); #endif logger(LOG_ERR, "Got signal %d", sig); dumperrstackstderr(); err = sigprocmask(SIG_SETMASK, &osamask, NULL); assert(err == 0); abort(); } void dbgpoint(long long int where) { #ifndef NDEBUG static unsigned int i = 0; if (where == 0) i = 0; if (i >= __DBGPOINTMAX) { i = 1; /* debug("i: %u, __DBGPOINTMAX: %u", i, __DBGPOINTMAX); return;*/ } dbgpoints[i].where = where; gettimeofday(&dbgpoints[i].tv, NULL); i++; #endif return; } int dbgredirectsignal(int signal) { int err; struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = &dumponsignal; err = sigaction(signal, &sa, NULL); return err; }