The idea here is to put "waypoints", in the program. When the program crashes on a signal, the signal handler displays the last waypoints before exiting.
Download: dbgpoint.h dbgpoint.c
dbgpoint.h
1: /* 2: * Debugging checkpoints 3: * 4: * Copyright 2008-2009 Nicolas Bernard <http://www.lafraze.net/nbernard/> 5: * All rights reserved. 6: * 7: * Permission to use, copy, modify, and distribute this software for any 8: * purpose with or without fee is hereby granted, provided that the above 9: * copyright notice and this permission notice appear in all copies. 10: * 11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18: * 19: */ 20: 21: #ifndef __DBGPOINT_H_ 22: #define __DBGPOINT_H_ 23: 24: #define __DBGPOINTMAX 30 25: 26: void dumponsignal(int sig); 27: 28: void dbgpoint(long long int where); 29: 30: int dbgredirectsignal(int sig); 31: 32: #endif /* ! __DBGPOINT_H_ */
dbgpoint.c
1: /* 2: * Debugging checkpoints 3: * 4: * Copyright 2008-2009 Nicolas Bernard <http://www.lafraze.net/nbernard/> 5: * All rights reserved. 6: * 7: * Permission to use, copy, modify, and distribute this software for any 8: * purpose with or without fee is hereby granted, provided that the above 9: * copyright notice and this permission notice appear in all copies. 10: * 11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18: * 19: */ 20: 21: #include <sys/time.h> 22: 23: #include <assert.h> 24: #include <signal.h> 25: #include <stdlib.h> 26: #include <string.h> 27: 28: #include "dbgpoint.h" 29: #include "debug.h" 30: 31: #ifndef NDEBUG 32: 33: unsigned int _dbgpointmax = 30; 34: 35: struct dbgpoint_data { 36: long long where; 37: struct timeval tv; 38: }; 39: 40: struct dbgpoint_data dbgpoints[__DBGPOINTMAX]; 41: 42: static void 43: dumpdbgpoints(void) 44: { 45: for (int i = 0; i < __DBGPOINTMAX; i++) { 46: struct timeval tv_tmp; 47: timersub(&dbgpoints[i].tv, &dbgpoints[0].tv, &tv_tmp); 48: 49: debug("%lld: %lu.%06lu -> %lu.%06lu", dbgpoints[i].where, 50: dbgpoints[i].tv.tv_sec, dbgpoints[i].tv.tv_usec, 51: tv_tmp.tv_sec, tv_tmp.tv_usec); 52: } 53: } 54: #endif /* ! NDEBUG */ 55: 56: void 57: dumponsignal(int sig) 58: { 59: sigset_t samask, osamask; 60: int err = sigfillset(&samask); 61: assert(err == 0); 62: err = sigprocmask(SIG_BLOCK, &samask, &osamask); 63: assert(err == 0); 64: #ifndef NDEBUG 65: dumpdbgpoints(); 66: #endif 67: logger(LOG_ERR, "[31;1mGot signal %d[0m", sig); 68: 69: dumperrstackstderr(); 70: 71: err = sigprocmask(SIG_SETMASK, &osamask, NULL); 72: assert(err == 0); 73: abort(); 74: } 75: 76: void 77: dbgpoint(long long int where) 78: { 79: #ifndef NDEBUG 80: static unsigned int i = 0; 81: 82: if (where == 0) 83: i = 0; 84: 85: if (i >= __DBGPOINTMAX) { 86: i = 1; 87: /* debug("i: %u, __DBGPOINTMAX: %u", i, __DBGPOINTMAX); 88: return;*/ 89: } 90: 91: dbgpoints[i].where = where; 92: gettimeofday(&dbgpoints[i].tv, NULL); 93: i++; 94: #endif 95: return; 96: } 97: 98: int 99: dbgredirectsignal(int signal) 100: { 101: int err; 102: struct sigaction sa; 103: memset(&sa, 0, sizeof(sa)); 104: sa.sa_handler = &dumponsignal; 105: err = sigaction(signal, &sa, NULL); 106: return err; 107: }