Download: debug.h debug.c
debug.h
1: /*
2: * Debugging fonctions
3: *
4: * Copyright 2004-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: /*
22: * IMPORTANT WARNING
23: *
24: * Beware of string format vulnerabilities: ensure an attacker cannot control
25: * the format string!
26: */
27:
28: #ifndef _DEBUG_H_
29: #define _DEBUG_H_
30:
31: #include <stdarg.h>
32: #include <stdio.h>
33: #include <stdlib.h>
34: #include <syslog.h>
35: #include <unistd.h>
36: #include "confloader/confloader.h"
37:
38: log_t logtype;
39:
40: FILE* logfiledesc;
41:
42: #ifndef WITHOUT_DEBUG_POS
43: #define debug(...) debugf(debug.h.html, 52, __func__, __VA_ARGS__)
44: #define panic(...) panicf(debug.h.html, 53, __func__, __VA_ARGS__)
45: #define logger(...) loggerf(debug.h.html, 54, __func__, __VA_ARGS__)
46: #ifdef _WITH_ERRSTACK_
47: #define stkdbg(...) stkdebugf(debug.h.html, 56, __func__, __VA_ARGS__)
48: #else
49: #define stkdbg(...) debugf(debug.h.html, 58, __func__, __VA_ARGS__)
50: #endif
51: #else
52: #define debug(...) debugf(NULL, 0, NULL, __VA_ARGS__)
53: #define panic(...) panicf(NULL, 0, NULL, __VA_ARGS__)
54: #define logger(...) loggerf(NULL, 0, NULL, __VA_ARGS__)
55: #ifdef _WITH_ERRSTACK_
56: #define stkdbg(...) stkdebugf(NULL, 0, NULL, __VA_ARGS__)
57: #else
58: #define stkdbg(...) debugf(NULL, 0, NULL, __VA_ARGS__)
59: #endif
60: #endif /* ! WITH_DEBUG_POS */
61:
62: void debugf(const char* file, int line, const char* func, const char* fmt, ...)
63: __attribute__ ((format (printf, 4, 5))); /* Flawfinder: ignore */
64: void panicf(const char* file, int line, const char* func, const char* fmt, ...)
65: __attribute__ ((format (printf, 4, 5), noreturn)); /* Flawfinder: ignore */
66: void loggerf(const char* file, int line, const char* func, int priority, const char* fmt, ...)
67: __attribute__ ((format (printf, 5, 6))); /* Flawfinder: ignore */
68:
69: //#define free(a) debugf(debug.h.html, 78, __func__, "free(%p)", (void*) a); free(a);
70: //#define close(a) 0; debugf(debug.h.html, 79, __func__, "close(%d)", a); close(a)
71: #define exit(a) {debugf(debug.h.html, 80, __func__, "exit(%d)", a); exit(a);};
72:
73: #include "dsession.h"
74: #define dsessionforceclosed(a) {debugf(debug.h.html, 83, __func__, "dsessionforceclosed(%p)", a); dsessionforceclosedf(a);};
75:
76: #ifdef _WITH_ERRSTACK_
77: void dumperrstack(log_t where);
78: void dumperrstackstderr(void); /* useful with atexit */
79: void flusherrstack(void); /* if the error was recovered and doesn't need to be
80: remembered... */
81: void stkdebugf(const char* file, int line, const char* func, const char* fmt, ...);
82: #endif /* _WITH_ERRSTACK_*/
83:
84: #endif /* _DEBUG_H_ */
debug.c
1: /*
2: * Debugging fonctions
3: *
4: * Copyright 2004-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/types.h>
22:
23: #include <assert.h>
24: #include <stdlib.h>
25: #include <string.h>
26: #include <unistd.h>
27:
28: #include "confloader/confloader.h"
29: #include "debug.h"
30:
31:
32: /** \todo: errstack is not compatible with priorities (dumperrstack LOG__SYSLOG
33: will dump everythink with priority LOG_ERR). */
34:
35:
36: #ifdef _WITH_ERRSTACK_
37:
38: #include "list.h"
39:
40: static list_t errorstack = -1;
41:
42: #endif /* _WITH_ERRSTACK_*/
43:
44:
45:
46: #define MAXLOGLINE 512
47:
48: static void
49: /* Flawfinder: ignore */ /* logline is a pointer */
50: pushlogline(char logline[MAXLOGLINE], int priority)
51: {
52: switch(logtype) {
53: case LOG__NOTDEF:
54: case LOG__STDERR:
55: case LOG__STDOUT:
56: logfiledesc = stderr;
57: if (logtype == LOG__STDOUT)
58: logfiledesc = stdout;
59: else
60: logfiledesc = stderr;
61: logtype = LOG__FILE;
62: case LOG__FILE:
63: fprintf(logfiledesc, "%s\n", logline);
64: break;
65: case LOG__SYSLOG:
66: /* The user of our fct must be wary of string format
67: vulnerabilities when using our fct and not only
68: when logtype is LOG__SYSLOG. */
69: syslog(priority, logline); /* Flawfinder: ignore */
70: break;
71: case LOG__NONE:
72: break;
73: #ifdef _WITH_ERRSTACK_
74: case LOG__ERRSTACK:
75: if (errorstack == -1) {
76: errorstack = list_create();
77: if (errorstack == -1)
78: return;
79: }
80: list_add_head(errorstack, logline);
81: break;
82: #endif
83: default:
84: case ELOG:
85: fprintf(stderr, "Log error, exiting\n");
86: break;
87: }
88: return;
89: }
90:
91: static void
92: logcommon(const char* file, int line, const char* func, int priority,
93: const char* fmt, va_list ap)
94: {
95: /* loglines are truncated */
96: char lbuf[MAXLOGLINE] = {0}; /* Flawfinder: ignore */
97: char *buf = lbuf;
98: int where = 0;
99:
100: #ifdef _WITH_ERRSTACK_
101: if (logtype == LOG__ERRSTACK) {
102: buf = calloc(MAXLOGLINE, sizeof(char));
103: if (buf == NULL) {
104: return;
105: }
106: }
107: #endif /* _WITH_ERRSTACK_*/
108:
109: if (file != NULL) {
110: assert(func != NULL);
111: /* Flawfinder: ignore */ /* We assume a C99-compliant system. */
112: where = snprintf(buf, MAXLOGLINE, "(%d)[%s:%d %s] ",
113: (int) getpid(), file, line, func);
114: }
115:
116: /* The user of our fct must be wary of string format
117: vulnerabilities when using our functions. */
118: /* Flawfinder: ignore */
119: (void) vsnprintf(buf + where, MAXLOGLINE - where, fmt, ap);
120:
121: pushlogline(buf, priority);
122: return;
123: }
124:
125: #ifdef _WITH_ERRSTACK_
126: void
127: dumperrstack(log_t where)
128: {
129: if (where == LOG__ERRSTACK)
130: return;
131: if (errorstack == -1)
132: return;
133:
134: log_t oldlt = logtype;
135: logtype = where;
136:
137: char* logline = list_get_tail(errorstack);
138: while (logline != NULL) {
139: pushlogline(logline, LOG_ERR);
140: list_del_tail(errorstack);
141: logline = list_get_tail(errorstack);
142: }
143:
144: logtype = oldlt;
145: return;
146: }
147:
148: void
149: dumperrstackstderr(void)
150: {
151: dumperrstack(LOG__STDERR);
152: }
153:
154: void
155: flusherrstack(void)
156: {
157: if (errorstack == -1)
158: return;
159: while(list_get_tail(errorstack) != NULL)
160: list_del_tail(errorstack);
161: }
162:
163: void
164: stkdebugf(const char* file, int line, const char* func, const char* fmt, ...)
165: {
166: log_t oldlt = logtype;
167: logtype = LOG__ERRSTACK;
168: va_list ap;
169: va_start(ap, fmt);
170: logcommon(file, line, func, LOG_DEBUG, fmt, ap);
171: va_end(ap);
172: logtype = oldlt;
173: }
174: #endif /* _WITH_ERRSTACK_*/
175:
176: void
177: debugf(const char* file, int line, const char* func, const char* fmt, ...)
178: {
179: #ifdef DEBUG
180: va_list ap;
181: va_start(ap, fmt);
182: logcommon(file, line, func, LOG_DEBUG, fmt, ap);
183: va_end(ap);
184: #endif /* DEBUG */
185: }
186:
187:
188: void
189: loggerf(const char* file, int line, const char* func, int priority, const char* fmt, ...)
190: {
191: va_list ap;
192: va_start(ap, fmt);
193: logcommon(file, line, func, priority, fmt, ap);
194: va_end(ap);
195: }
196:
197: void
198: panicf(const char* file, int line, const char* func, const char* fmt, ...)
199: {
200: va_list ap;
201: va_start(ap, fmt);
202: #ifdef _WITH_ERRSTACK_
203: dumperrstack(LOG__STDERR);
204: #endif
205: logcommon(file, line, func, LOG_ERR, fmt, ap);
206: va_end(ap);
207: abort();
208: }