2 This file is part of the NoBug debugging library.
4 Copyright (C) 2007, 2008, Christian Thaeter <chth@gmx.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, contact Christian Thaeter <ct@pipapo.org>.
22 #ifndef NOBUG_LIBNOBUG_C /* not when building libnobug */
25 #error NDEBUG incompatible with -DEBUG_ALPHA
28 #error NDEBUG incompatible with -DEBUG_BETA
32 #if defined(EBUG_ALPHA)
33 # define NOBUG_MODE_ALPHA 1
34 # define NOBUG_MODE_BETA 0
35 # define NOBUG_MODE_RELEASE 0
36 #elif defined(EBUG_BETA)
37 # define NOBUG_MODE_ALPHA 0
38 # define NOBUG_MODE_BETA 1
39 # define NOBUG_MODE_RELEASE 0
41 # define NOBUG_MODE_ALPHA 0
42 # define NOBUG_MODE_BETA 0
43 # define NOBUG_MODE_RELEASE 1
45 #error no debug level and no NDEBUG defined
47 #endif /* NOBUG_LIBNOBUG_C */
59 #ifdef HAVE_EXECINFO_H
60 # ifndef NOBUG_USE_EXECINFO
61 # define NOBUG_USE_EXECINFO 1
64 # undef NOBUG_USE_EXECINFO
65 # define NOBUG_USE_EXECINFO 0
68 #if NOBUG_USE_EXECINFO
72 #if defined(HAVE_VALGRIND_VALGRIND_H) && !defined(NVALGRIND)
73 # ifndef NOBUG_USE_VALGRIND
74 # define NOBUG_USE_VALGRIND 1
77 # undef NOBUG_USE_VALGRIND
78 # define NOBUG_USE_VALGRIND 0
81 #if NOBUG_USE_VALGRIND
82 #include <valgrind/valgrind.h>
86 # ifndef NOBUG_USE_PTHREAD
87 # define NOBUG_USE_PTHREAD 1
90 # ifdef NOBUG_USE_PTHREAD
91 # undef NOBUG_USE_PTHREAD
93 # define NOBUG_USE_PTHREAD 0
101 #ifndef NOBUG_LIBNOBUG_C /* not when building libnobug */
105 #if NOBUG_MODE_RELEASE==0
107 #define assert(expr) NOBUG_ASSERT(expr)
111 check preconditions (incoming parameters)
114 #define NOBUG_REQUIRE(expr, ...) \
115 NOBUG_IF_NOT_RELEASE(NOBUG_ASSERT_(expr, "PRECONDITION", \
116 NOBUG_LOCATION_INFO, ## __VA_ARGS__))
119 #define NOBUG_REQUIRE_DBG(expr, ...) \
120 NOBUG_IF_NOT_RELEASE(NOBUG_ASSERT_DBG_(expr, "PRECONDITION", \
121 NOBUG_LOCATION_INFO, ## __VA_ARGS__))
124 #define NOBUG_REQUIRE_IF(when, expr, ...) \
125 NOBUG_WHEN(when, NOBUG_REQUIRE(expr, ## __VA_ARGS__))
127 #define NOBUG_REQUIRE_IF_DBG(when, expr, ...) \
128 NOBUG_WHEN(when, NOBUG_REQUIRE_DBG(expr, ## __VA_ARGS__))
131 check postcondistions (computation outcomes)
133 #define NOBUG_ENSURE(expr, ...) \
135 NOBUG_ASSERT_(expr, "POSTCONDITION", \
136 NOBUG_LOCATION_INFO, ## __VA_ARGS__), \
138 if (NOBUG_SCOPE_UNCHECKED) \
140 NOBUG_ASSERT_(expr, "POSTCONDITION", \
141 NOBUG_LOCATION_INFO, ## __VA_ARGS__); \
147 #define NOBUG_ENSURE_DBG(expr, ...) \
149 NOBUG_ASSERT_DBG_(expr, "POSTCONDITION", \
150 NOBUG_LOCATION_INFO, ## __VA_ARGS__), \
152 if (NOBUG_SCOPE_UNCHECKED) \
154 NOBUG_ASSERT_DBG_(expr, "POSTCONDITION", \
155 NOBUG_LOCATION_INFO, ## __VA_ARGS__); \
161 #define NOBUG_ENSURE_IF(when, expr, ...) \
162 NOBUG_WHEN(when, NOBUG_ENSURE(expr, ## __VA_ARGS__))
164 #define NOBUG_ENSURE_IF_DBG(when, expr, ...) \
165 NOBUG_WHEN(when, NOBUG_ENSURE_DBG(expr, ## __VA_ARGS__))
172 #define NOBUG_ASSERT(expr, ...) \
173 NOBUG_IF_NOT_RELEASE( \
175 NOBUG_ASSERT_(expr, "ASSERTION", NOBUG_LOCATION_INFO, ## __VA_ARGS__) \
178 #define NOBUG_ASSERT_DBG(expr, ...) \
179 NOBUG_IF_NOT_RELEASE( \
181 NOBUG_ASSERT_DBG_(expr, "ASSERTION", \
182 NOBUG_LOCATION_INFO, ## __VA_ARGS__); \
186 #define NOBUG_ASSERT_IF(when, expr, ...) \
187 NOBUG_WHEN(when, NOBUG_ASSERT(expr, ## __VA_ARGS__))
189 #define NOBUG_ASSERT_IF_DBG(when, expr, ...) \
190 NOBUG_WHEN(when, NOBUG_ASSERT_DBG(expr, ## __VA_ARGS__))
195 #define NOBUG_ASSERT_(expr, what, location, ...) \
196 if (NOBUG_EXPECT_FALSE(!(expr))) \
198 NOBUG_LOG_( NOBUG_ON, LOG_EMERG, \
199 location, what, "(%s) " \
200 NOBUG_HEAD(__VA_ARGS__), \
201 #expr NOBUG_TAIL(__VA_ARGS__)); \
206 #define NOBUG_ASSERT_DBG_(expr, what, location, ...) \
207 NOBUG_IF_DBG_ACTIVE( \
208 if (NOBUG_EXPECT_FALSE(!(expr))) \
210 NOBUG_LOG_( NOBUG_ON, LOG_EMERG, \
211 location, what, "(%s) " \
212 NOBUG_HEAD(__VA_ARGS__), \
213 #expr NOBUG_TAIL(__VA_ARGS__)); \
218 #define NOBUG_ASSERTN_(expr, what, location, ...) \
219 if (NOBUG_EXPECT_FALSE(!(expr))) \
221 NOBUG_LOG_( NOBUG_ON, LOG_EMERG, \
233 #define NOBUG_INVARIANT(type, pointer, depth) \
236 if (NOBUG_SCOPE_UNCHECKED) \
238 NOBUG_CAT(type,_invariant)(pointer, depth, \
239 NOBUG_LOCATION_ARGS); \
242 NOBUG_PASS, NOBUG_PASS \
245 #define NOBUG_INVARIANT_DBG(type, pointer, ...) \
247 NOBUG_IF_DBG_ACTIVE ( \
248 if (NOBUG_SCOPE_UNCHECKED) \
250 NOBUG_CAT(type,_invariant)(pointer, depth, NOBUG_LOCATION_ARGS); \
253 NOBUG_PASS, NOBUG_PASS \
256 #define NOBUG_INVARIANT_IF(when, type, pointer, ...) \
257 NOBUG_WHEN(when, NOBUG_INVARIANT(type, pointer, ## __VA_ARGS__))
259 #define NOBUG_INVARIANT_IF_DBG(when, type, pointer, ...) \
260 NOBUG_WHEN(when, NOBUG_INVARIANT_DBG(type, pointer, ## __VA_ARGS__))
262 #define NOBUG_INVARIANT_ASSERT(expr, ...) \
263 NOBUG_ASSERT_(expr, "INVARIANT", (file, line, func), ## __VA_ARGS__)
267 dumping datastructures
269 /*TODO dump-level for flags instead limits[0]*/
270 #define NOBUG_DUMP(flag, type, pointer, depth) \
271 NOBUG_IF_NOT_RELEASE( \
273 if (NOBUG_EXPECT_FALSE (NOBUG_DUMP_LEVEL <= nobug_flag_##flag.limits[0])) \
276 NOBUG_CAT3(nobug_, type, _dump)(pointer, depth, \
277 NOBUG_LOCATION_ARGS); \
281 #define NOBUG_DUMP_DBG(flag, type, pointer, depth) \
282 NOBUG_IF_NOT_RELEASE( \
284 NOBUG_IF_DBG_ACTIVE ( \
285 if (NOBUG_EXPECT_FALSE(NOBUG_DUMP_LEVEL <= nobug_flag_##flag.limits[0])) \
287 NOBUG_CAT3(nobug_, type, _dump)(pointer, depth, \
288 NOBUG_LOCATION_ARGS); \
292 #define NOBUG_DUMP_IF(expr, flag, type, pointer, depth) \
294 if (NOBUG_EXPECT_FALSE(NOBUG_DUMP_LEVEL <= nobug_flag_##flag.limits[0])) \
296 if (NOBUG_EXPECT_FALSE(expr)) \
298 NOBUG_CAT3(nobug_, type,_dump)(pointer, depth, \
299 NOBUG_LOCATION_ARGS); \
303 #define NOBUG_DUMP_IF_DBG(expr, flag, type, pointer, depth) \
304 NOBUG_IF_NOT_RELEASE( \
305 NOBUG_IF_DBG_ACTIVE ( \
306 if (NOBUG_EXPECT_FALSE(NOBUG_DUMP_LEVEL <= nobug_flag_##flag.limits[0])) \
308 if (NOBUG_EXPECT_FALSE(expr)) \
310 NOBUG_CAT(nobug_, type,_dump)(pointer, depth, \
311 NOBUG_LOCATION_ARGS); \
315 #ifndef NOBUG_DUMP_LEVEL
316 #define NOBUG_DUMP_LEVEL LOG_DEBUG
319 #define NOBUG_DUMP_LOG(fmt, ...) \
320 NOBUG_LOG_( NOBUG_ON, NOBUG_DUMP_LEVEL, \
321 (file, line, func), "DUMP", \
325 #define NOBUG_DUMP_LOG_DBG(fmt, ...) \
326 NOBUG_IF_DBG_ACTIVE ( \
327 NOBUG_LOG_( NOBUG_ON, NOBUG_DUMP_LEVEL, \
328 (file, line, func), "DUMP", \
329 fmt, ## __VA_ARGS__) \
332 #define NOBUG_DUMP_LOG_IF(expr, fmt, ...) \
334 if (NOBUG_EXPECT_FALSE(expr)) { \
335 NOBUG_LOG_( NOBUG_ON, NOBUG_DUMP_LEVEL, \
336 (file, line, func), "DUMP", \
337 fmt, ## __VA_ARGS__) \
341 #define NOBUG_DUMP_LOG_IF_DBG(expr, fmt, ...) \
342 NOBUG_IF_DBG_ACTIVE ( \
343 if (NOBUG_EXPECT_FALSE(expr)) { \
344 NOBUG_LOG_( NOBUG_ON, NOBUG_DUMP_LEVEL, \
345 (file), line, func), "DUMP", \
346 fmt, ## __VA_ARGS__) \
354 #define NOBUG_LOG(flag, lvl, ...) \
356 NOBUG_LOG_(flag, lvl, NOBUG_LOCATION_INFO, \
357 NOBUG_LVL(lvl), ## __VA_ARGS__); \
360 #define NOBUG_LOG_DBG(flag, lvl, ...) \
361 NOBUG_IF_DBG_ACTIVE ( \
362 NOBUG_LOG_(flag, lvl, NOBUG_LOCATION_INFO, \
363 NOBUG_LVL(lvl), ## __VA_ARGS__); \
366 #define NOBUG_LOG_IF(expr, flag, lvl, ...) \
368 if (NOBUG_EXPECT_FALSE(expr)) { \
369 NOBUG_LOG_(flag, lvl, NOBUG_LOCATION_INFO, \
370 NOBUG_LVL(lvl), ## __VA_ARGS__); \
374 #define NOBUG_LOG_IF_DBG(expr, flag, lvl, ...) \
375 NOBUG_IF_DBG_ACTIVE ( \
376 if (NOBUG_EXPECT_FALSE(expr)) { \
377 NOBUG_LOG_(flag, lvl, NOBUG_LOCATION_INFO, \
378 NOBUG_LVL(lvl), ## __VA_ARGS__); \
382 #define NOBUG_LVL(lvl) NOBUG_LVL_##lvl
383 #define NOBUG_LVL_0 "EMERG"
384 #define NOBUG_LVL_1 "ALERT"
385 #define NOBUG_LVL_2 "CRIT"
386 #define NOBUG_LVL_3 "ERR"
387 #define NOBUG_LVL_4 "WARNING"
388 #define NOBUG_LVL_5 "NOTICE"
389 #define NOBUG_LVL_6 "INFO"
390 #define NOBUG_LVL_7 "TRACE"
394 low level logging handler
396 #define NOBUG_LOG_(flag, lvl, location, what, ...) \
398 if (NOBUG_EXPECT_FALSE(lvl <= NOBUG_FLAG(flag).limits[NOBUG_TARGET_RINGBUFFER])) \
401 nobug_log (&NOBUG_FLAG(flag), lvl, \
402 "%0.8llu: %s:%d: %s:"NOBUG_THREAD_ID_FMT(" ",":")" %s: "NOBUG_HEAD(__VA_ARGS__), \
403 ++nobug_counter, NOBUG_LOCATION_FILE location, NOBUG_LOCATION_LINE location, \
404 what NOBUG_THREAD_ID_COMMA, \
405 NOBUG_LOCATION_FUNC location NOBUG_TAIL(__VA_ARGS__)); \
411 #define NOBUG_LOCATION_ARGS NOBUG_BASENAME(__FILE__), __LINE__, __func__
412 #define NOBUG_LOCATION_INFO (NOBUG_LOCATION_ARGS)
414 #define NOBUG_LOCATION_FILE(file, _1, _2) file
415 #define NOBUG_LOCATION_LINE(_1, line, _2) line
416 #define NOBUG_LOCATION_FUNC(_1, _2, func) func
419 /*TODO better location handling, no text? empty on RELEASE*/
420 #define NOBUG_LOCATION(text) \
422 NOBUG_BASENAME(__FILE__ ":" NOBUG_STRINGIZE(__LINE__)":" text), \
423 NOBUG_BASENAME(__FILE__ ":" NOBUG_STRINGIZE(__LINE__)":" text), \
427 #define NOBUG_ERROR(flag, ...) \
428 NOBUG_LOG(flag, LOG_ERR, ## __VA_ARGS__)
429 #define NOBUG_ERROR_IF(expr, flag, ...) \
430 NOBUG_LOG_IF(expr, flag, LOG_ERR, ## __VA_ARGS__)
431 #define NOBUG_ERROR_DBG(flag, ...) \
432 NOBUG_LOG_DBG(flag, LOG_ERR, ## __VA_ARGS__)
433 #define NOBUG_ERROR_IF_DBG(expr, flag, ...) \
434 NOBUG_LOG_IF_DBG(expr, flag, LOG_ERR, ## __VA_ARGS__)
436 #define NOBUG_WARN(flag, ...) \
437 NOBUG_LOG(flag, LOG_WARNING, ## __VA_ARGS__)
438 #define NOBUG_WARN_IF(expr, flag, ...) \
439 NOBUG_LOG_IF(expr, flag, LOG_WARNING, ## __VA_ARGS__)
440 #define NOBUG_WARN_DBG(flag, ...) \
441 NOBUG_LOG_DBG(flag, LOG_WARNING, ## __VA_ARGS__)
442 #define NOBUG_WARN_IF_DBG(expr, flag, ...) \
443 NOBUG_LOG_IF_DBG(expr, flag, LOG_WARNING, ## __VA_ARGS__)
445 #define NOBUG_INFO(flag, ...) \
446 NOBUG_LOG(flag, LOG_INFO, ## __VA_ARGS__)
447 #define NOBUG_INFO_IF(expr, flag, ...) \
448 NOBUG_LOG_IF(expr, flag, LOG_INFO, ## __VA_ARGS__)
449 #define NOBUG_INFO_DBG(flag, ...) \
450 NOBUG_LOG_DBG(flag, LOG_INFO, ## __VA_ARGS__)
451 #define NOBUG_INFO_IF_DBG(expr, flag, ...) \
452 NOBUG_LOG_IF_DBG(expr, flag, LOG_INFO, ## __VA_ARGS__)
454 #define NOBUG_NOTICE(flag, ...) \
455 NOBUG_LOG(flag, LOG_NOTICE, ## __VA_ARGS__)
456 #define NOBUG_NOTICE_IF(expr, flag, ...) \
457 NOBUG_LOG_IF(expr, flag, LOG_NOTICE, ## __VA_ARGS__)
458 #define NOBUG_NOTICE_DBG(flag, ...) \
459 NOBUG_LOG_DBG(flag, LOG_NOTICE, ## __VA_ARGS__)
460 #define NOBUG_NOTICE_IF_DBG(expr, flag, ...) \
461 NOBUG_LOG_IF_DBG(expr, flag, LOG_NOTICE, ## __VA_ARGS__)
463 #define NOBUG_TRACE(flag, ...) \
464 NOBUG_LOG(flag, LOG_DEBUG, ## __VA_ARGS__)
465 #define NOBUG_TRACE_IF(expr, flag, ...) \
466 NOBUG_LOG_IF(expr, flag, LOG_DEBUG, ## __VA_ARGS__)
467 #define NOBUG_TRACE_DBG(flag, ...) \
468 NOBUG_LOG_DBG(flag, LOG_DEBUG, ## __VA_ARGS__)
469 #define NOBUG_TRACE_IF_DBG(expr, flag, ...) \
470 NOBUG_LOG_IF_DBG(expr, flag, LOG_DEBUG, ## __VA_ARGS__)
472 #define NOBUG_BASENAME(name) (strrchr((name), '/')?strrchr((name), '/') + 1 : (name))
474 #define NOBUG_SCOPE_UNCHECKED NOBUG_CHECKED_VALUE == 0
476 #define NOBUG_DBG_ACTIVE \
477 NOBUG_IF(NOBUG_USE_VALGRIND, (RUNNING_ON_VALGRIND?2:0)) \
478 NOBUG_IFNOT(NOBUG_USE_VALGRIND, (0))
482 unchecked Preconditions, Postconditions, Invariants Preconditions, Postconditions compiling will abort
483 checked Preconditions, Postconditions Preconditions
486 #define NOBUG_CHECKED NOBUG_IF_NOT_RELEASE(enum {NOBUG_CHECKED_VALUE=1})
488 #define NOBUG_UNCHECKED \
489 NOBUG_IF_NOT_RELEASE(enum {NOBUG_CHECKED_VALUE=0}) \
490 NOBUG_IF(NOBUG_MODE_RELEASE, NOBUG_UNCHECKED_NOT_ALLOWED_IN_RELEASE_BUILD)
492 #define NOBUG_ABORT abort()
494 #define NOBUG_DBG_GDB 1
495 #define NOBUG_DBG_VALGRIND 2
497 #define NOBUG_BACKTRACE \
499 switch (NOBUG_DBG_ACTIVE) { \
500 case NOBUG_DBG_VALGRIND: \
501 NOBUG_BACKTRACE_VALGRIND; \
504 NOBUG_BACKTRACE_GLIBC; \
506 NOBUG_BACKTRACE_GLIBC, \
507 NOBUG_BACKTRACE_GLIBC \
510 #define NOBUG_BACKTRACE_DBG \
511 NOBUG_IF_NOT_RELEASE( \
512 switch (NOBUG_DBG_ACTIVE) { \
513 case NOBUG_DBG_VALGRIND: \
514 NOBUG_BACKTRACE_VALGRIND; \
518 #define NOBUG_BACKTRACE_GDB fprintf(stderr, "UNIMPLEMENTED : GDB Backtraces\n")
520 #define NOBUG_BACKTRACE_VALGRIND \
521 NOBUG_IF(NOBUG_USE_VALGRIND, \
522 VALGRIND_PRINTF_BACKTRACE("BACKTRACE : %s@%d %s", \
523 NOBUG_LOCATION_INFO))
526 #ifndef NOBUG_BACKTRACE_DEPTH
527 #define NOBUG_BACKTRACE_DEPTH 256
530 #define NOBUG_BACKTRACE_GLIBC \
531 NOBUG_IF_NOT_RELEASE( \
533 NOBUG_IF(NOBUG_USE_EXECINFO, \
534 void* nobug_backtrace_buffer[NOBUG_BACKTRACE_DEPTH]; \
535 backtrace_symbols_fd (nobug_backtrace_buffer, \
536 backtrace (nobug_backtrace_buffer, NOBUG_BACKTRACE_DEPTH), 2))))
541 DEPRECATED log nothing wont compile
543 #define NOBUG_DEPRECATED(msg) \
546 NOBUG_LOG_ (NOBUG_ON, LOG_ALERT, NOBUG_LOCATION_INFO, \
547 "DEPRECATED", msg); \
550 NOBUG_DEPRECATED_NOT_ALLOWED_IN_RELEASE_BUILD(msg) \
555 UNIMPLEMENTED abort abort wont compile
557 #define NOBUG_UNIMPLEMENTED(msg) \
558 NOBUG_IF_NOT_RELEASE ( \
560 NOBUG_LOG_ (NOBUG_ON, LOG_EMERG, NOBUG_LOCATION_INFO, \
561 "UNIMPLEMENTED", msg); \
564 NOBUG_IF(NOBUG_MODE_RELEASE, NOBUG_UNIMPLEMENTED_NOT_ALLOWED_IN_RELEASE_BUILD(msg);)
568 FIXME log wont compile wont compile
570 #define NOBUG_FIXME(msg) \
573 NOBUG_LOG_ (NOBUG_ON, LOG_ALERT, NOBUG_LOCATION_INFO, \
576 NOBUG_FIXME_NOT_ALLOWED_IN_BETA_BUILD(msg), \
577 NOBUG_FIXME_NOT_ALLOWED_IN_RELEASE_BUILD(msg) \
582 TODO log log wont compile
584 #define NOBUG_TODO(msg) \
585 NOBUG_IF_NOT_RELEASE ( \
587 NOBUG_LOG_( NOBUG_ON, LOG_CRIT, NOBUG_LOCATION_INFO, \
590 NOBUG_IF(NOBUG_MODE_RELEASE, NOBUG_TODO_NOT_ALLOWED_IN_RELEASE_BUILD(msg);)
594 PLANNED log nothing nothing
596 #define NOBUG_PLANNED(msg) \
597 NOBUG_MODE_SWITCH ( \
599 NOBUG_LOG_ (NOBUG_ON, LOG_INFO, NOBUG_LOCATION_INFO, \
602 NOBUG_PASS,NOBUG_PASS \
607 NOTREACHED abort abort nothing
609 #define NOBUG_NOTREACHED \
610 NOBUG_IF_NOT_RELEASE ( \
612 NOBUG_LOG_( NOBUG_ON, LOG_EMERG, NOBUG_LOCATION_INFO, \
617 NOBUG_IF(NOBUG_MODE_RELEASE, NOBUG_PASS)
621 Resource registry macros
623 #ifndef NOBUG_RESOURCE_LOGGING
624 #define NOBUG_RESOURCE_LOGGING 1
627 #ifndef NOBUG_RESOURCE_LOG_LEVEL
628 #define NOBUG_RESOURCE_LOG_LEVEL LOG_DEBUG
631 #define NOBUG_RESOURCE_HANDLE(handle) \
632 NOBUG_IF(NOBUG_MODE_ALPHA, \
633 struct nobug_resource_record* handle)
635 #define NOBUG_RESOURCE_ANNOUNCE(flag, type, name, ptr, handle) \
636 NOBUG_IF(NOBUG_MODE_ALPHA, \
637 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
638 NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
639 "RESOURCE_ANNOUNCE", "%s: %s@%p", type, name, ptr);) \
640 NOBUG_ASSERTN_(handle = nobug_resource_announce (type, name, ptr, \
641 NOBUG_BASENAME(__FILE__ ":" NOBUG_STRINGIZE(__LINE__))), \
642 "RESOURCE_ANNOUNCE", NOBUG_LOCATION_INFO, "%s: %s@%p %s", \
643 type, name, ptr, nobug_resource_error) \
646 #define NOBUG_RESOURCE_FORGET(flag, handle) \
647 NOBUG_IF(NOBUG_MODE_ALPHA, \
648 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
649 NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
650 "RESOURCE_FORGET", "%s: %s@%p", handle?handle->type:"", \
651 handle?handle->name:"", handle?handle->object_id:NULL);) \
652 NOBUG_ASSERTN_(nobug_resource_forget (handle), \
653 "RESOURCE_FORGET", NOBUG_LOCATION_INFO, "%s: %s@%p: %s", \
654 handle?handle->type:"", handle?handle->name:"", \
655 handle?handle->object_id:NULL, nobug_resource_error); \
659 #define NOBUG_RESOURCE_ENTER(flag, resource, user, ptr, state, handle) \
660 NOBUG_IF(NOBUG_MODE_ALPHA, \
661 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
662 NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
663 "RESOURCE_ENTER", "%s: %s@%p: %s@%p: %s", \
664 resource->type, resource->name, resource->object_id, \
665 user, ptr, nobug_resource_states[state]);) \
666 NOBUG_ASSERTN_(handle = nobug_resource_enter (resource, user, ptr, state, \
667 NOBUG_BASENAME(__FILE__ ":" NOBUG_STRINGIZE(__LINE__))), \
668 "RESOURCE_ENTER", NOBUG_LOCATION_INFO, "%s: %s@%p: %s@%p: %s: %s", \
669 resource?resource->type:"", resource?resource->name:"", \
670 resource?resource->object_id:NULL, \
671 user, ptr, nobug_resource_states[state], nobug_resource_error) \
674 #define NOBUG_RESOURCE_STATE(flag, resource, state) \
675 NOBUG_IF(NOBUG_MODE_ALPHA, \
676 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
677 NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
678 "RESOURCE_STATE", "%s: %s@%p: %s@%p: %s->%s", \
679 resource?((struct nobug_resource_record*)resource->data)->type:"", \
680 resource?((struct nobug_resource_record*)resource->data)->name:"", \
681 resource?((struct nobug_resource_record*)resource->data)->object_id:"", \
682 resource?resource->name:NULL, \
683 resource?resource->object_id:NULL, \
684 resource?resource->type:"", nobug_resource_states[state]); \
686 NOBUG_ASSERTN_(nobug_resource_state (resource, state), \
687 "RESOURCE_ENTER", NOBUG_LOCATION_INFO, "%s: %s@%p: %s@%p: %s->%s: %s", \
688 resource?((struct nobug_resource_record*)resource->data)->type:"", \
689 resource?((struct nobug_resource_record*)resource->data)->name:"", \
690 resource?((struct nobug_resource_record*)resource->data)->object_id:"", \
691 resource?resource->name:NULL, \
692 resource?resource->object_id:NULL, \
693 resource?resource->type:"", nobug_resource_states[state], \
694 nobug_resource_error) \
697 #define NOBUG_RESOURCE_LEAVE(flag, handle) \
698 NOBUG_IF(NOBUG_MODE_ALPHA, \
699 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
700 NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
701 "RESOURCE_LEAVE", "%s: %s@%p: %s@%p: %s", \
702 handle?((struct nobug_resource_record*)handle->data)->type:"", \
703 handle?((struct nobug_resource_record*)handle->data)->name:"", \
704 handle?((struct nobug_resource_record*)handle->data)->object_id:"", \
705 handle?handle->name:"", \
706 handle?handle->object_id:NULL, \
707 handle?handle->type:""); \
709 NOBUG_ASSERTN_(nobug_resource_leave (handle), \
710 "RESOURCE_LEAVE", NOBUG_LOCATION_INFO, "%s: %s@%p: %s@%p: %s: %s", \
711 handle?((struct nobug_resource_record*)handle->data)->type:"", \
712 handle?((struct nobug_resource_record*)handle->data)->name:"", \
713 handle?((struct nobug_resource_record*)handle->data)->object_id:"", \
714 handle?handle->name:NULL, \
715 handle?handle->object_id:NULL, \
716 handle?handle->type:"", \
717 nobug_resource_error); \
720 #define NOBUG_RESOURCE_LEAVE_LOOKUP(flag, handle, ptr) \
721 NOBUG_IF(NOBUG_MODE_ALPHA, \
722 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
723 NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
724 "RESOURCE_LEAVE", "%s: %s@%p: @%p", \
725 handle?handle->type:"", \
726 handle?handle->name:"", \
727 handle?handle->object_id:"", \
730 NOBUG_ASSERTN_(nobug_resource_leave (nobug_resource_find(handle, ptr)), \
731 "RESOURCE_LEAVE", NOBUG_LOCATION_INFO, "%s: %s@%p: @%p: %s", \
732 handle?handle->type:"", \
733 handle?handle->name:"", \
734 handle?handle->object_id:"", \
735 ptr, nobug_resource_error) \
741 #if NOBUG_USE_PTHREAD
742 #define NOBUG_LOCK pthread_mutex_lock (&nobug_global_mutex)
743 #define NOBUG_UNLOCK pthread_mutex_unlock (&nobug_global_mutex)
745 #define NOBUG_THREAD_ID_SET(name) nobug_thread_id_set(name)
746 #define NOBUG_THREAD_ID_FMT(pre,post) pre "%s" post
747 #define NOBUG_THREAD_ID_COMMA , NOBUG_THREAD_ID_GET
748 #define NOBUG_THREAD_ID_GET nobug_thread_id_get()
753 #define NOBUG_THREAD_ID_SET(name)
754 #define NOBUG_THREAD_ID_FMT(pre,post) ""
755 #define NOBUG_THREAD_ID_COMMA
756 #define NOBUG_THREAD_ID_GET ""
762 #define NOBUG_INIT nobug_init()
769 #define NOBUG_CLEANUP(fn) \
770 NOBUG_IF(NOBUG_MODE_ALPHA, \
771 __attribute__((cleanup(fn))) \
774 #define NOBUG_CLEANUP(fn)
777 #define NOBUG_ONCE(code) \
779 static int NOBUG_CAT(nobug_once_,__LINE__) = 0; \
780 if (NOBUG_EXPECT_FALSE(!NOBUG_CAT(nobug_once_,__LINE__))) \
782 NOBUG_CAT(nobug_once_,__LINE__) = 1; \
789 #define NOBUG_BLOCK(code) do { code; } while (0)
791 #define NOBUG_IF_DBG_ACTIVE(code) \
792 NOBUG_IF(NOBUG_MODE_ALPHA, \
794 if (NOBUG_EXPECT_FALSE(NOBUG_DBG_ACTIVE)) \
800 NOBUG_IF(NOBUG_NOT(NOBUG_MODE_ALPHA), NOBUG_PASS)
802 #define NOBUG_WHEN(when, code) \
803 NOBUG_IF_NOT_RELEASE(do{ if (when){code;}}while(0))
805 #define NOBUG_IF_NOT_RELEASE(code) \
806 NOBUG_IF(NOBUG_NOT(NOBUG_MODE_RELEASE), code) \
807 NOBUG_IF(NOBUG_MODE_RELEASE, NOBUG_PASS)
809 #define NOBUG_MODE_SWITCH(alpha_code, beta_code, release_code) \
810 NOBUG_IF(NOBUG_MODE_ALPHA, alpha_code) \
811 NOBUG_IF(NOBUG_MODE_BETA, beta_code) \
812 NOBUG_IF(NOBUG_MODE_RELEASE, release_code)
817 #define NOBUG_FLAG(name) NOBUG_CAT(nobug_flag_,name)
819 #define NOBUG_DEFINE_FLAG(name) struct nobug_flag NOBUG_FLAG(name) = \
820 NOBUG_IF(NOBUG_MODE_ALPHA, {#name, NULL, 0, \
821 {LOG_DEBUG, LOG_INFO, LOG_DEBUG, -1, LOG_INFO}, &nobug_default_ringbuffer, NULL,NULL}) \
822 NOBUG_IF(NOBUG_MODE_BETA, {#name, NULL, 0, \
823 {LOG_INFO, LOG_NOTICE, LOG_NOTICE, LOG_NOTICE, LOG_WARNING}, &nobug_default_ringbuffer, NULL,NULL}) \
824 NOBUG_IF(NOBUG_MODE_RELEASE, {#name, NULL, 0, \
825 {LOG_NOTICE, -1, LOG_WARNING, LOG_WARNING, LOG_ERR}, &nobug_default_ringbuffer, NULL,NULL})
827 #define NOBUG_DEFINE_FLAG_PARENT(name, parent) \
828 NOBUG_DECLARE_FLAG(parent); \
829 struct nobug_flag NOBUG_FLAG(name) = \
830 NOBUG_IF(NOBUG_MODE_ALPHA, {#name, &NOBUG_FLAG(parent), 0, \
831 {LOG_DEBUG, LOG_INFO, LOG_DEBUG, -1, LOG_INFO}, &nobug_default_ringbuffer, NULL,NULL}) \
832 NOBUG_IF(NOBUG_MODE_BETA, {#name, &NOBUG_FLAG(parent), 0, \
833 {LOG_INFO, LOG_NOTICE, LOG_NOTICE, LOG_NOTICE, LOG_WARNING}, &nobug_default_ringbuffer, NULL,NULL}) \
834 NOBUG_IF(NOBUG_MODE_RELEASE, {#name, &NOBUG_FLAG(parent), 0, \
835 {LOG_NOTICE, -1, LOG_WARNING, LOG_WARNING, LOG_ERR}, &nobug_default_ringbuffer, NULL,NULL})
837 #define NOBUG_DEFINE_FLAG_LIMIT(name, limit) struct nobug_flag NOBUG_FLAG(name) = \
838 NOBUG_IF(NOBUG_MODE_ALPHA, {#name, NULL, 0, \
839 {LOG_DEBUG, limit, LOG_DEBUG, -1, LOG_INFO}, &nobug_default_ringbuffer, NULL,NULL}) \
840 NOBUG_IF(NOBUG_MODE_BETA, {#name, NULL, 0, \
841 {LOG_INFO, LOG_NOTICE, limit, LOG_NOTICE, LOG_WARNING}, &nobug_default_ringbuffer, NULL,NULL}) \
842 NOBUG_IF(NOBUG_MODE_RELEASE, {#name, NULL, 0, \
843 {LOG_NOTICE, -1, LOG_WARNING, limit, LOG_ERR}, &nobug_default_ringbuffer, NULL,NULL})
845 #define NOBUG_DEFINE_FLAG_PARENT_LIMIT(name, parent, limit) \
846 NOBUG_DECLARE_FLAG(parent); \
847 struct nobug_flag NOBUG_FLAG(name) = \
848 NOBUG_IF(NOBUG_MODE_ALPHA, {#name, &NOBUG_FLAG(parent), 0, \
849 {LOG_DEBUG, limit, LOG_DEBUG, -1, LOG_INFO}, &nobug_default_ringbuffer, NULL,NULL}) \
850 NOBUG_IF(NOBUG_MODE_BETA, {#name, &NOBUG_FLAG(parent), 0, \
851 {LOG_INFO, LOG_NOTICE, limit, LOG_NOTICE, LOG_WARNING}, &nobug_default_ringbuffer, NULL,NULL}) \
852 NOBUG_IF(NOBUG_MODE_RELEASE, {#name, &NOBUG_FLAG(parent), 0, \
853 {LOG_NOTICE, -1, LOG_WARNING, limit, LOG_ERR}, &nobug_default_ringbuffer, NULL,NULL})
856 /*TODO better FLAG_LIMIT handling, should respect LOG_TARGET */
859 #define NOBUG_DECLARE_FLAG(name) extern struct nobug_flag NOBUG_FLAG(name)
861 #define NOBUG_INIT_FLAG(name) \
862 nobug_env_init_flag (&NOBUG_FLAG(name), NOBUG_LOG_TARGET, NOBUG_LOG_LIMIT)
864 #define NOBUG_INIT_FLAG_LIMIT(name, default) \
865 nobug_env_init_flag (&NOBUG_FLAG(name), NOBUG_LOG_TARGET, default)
868 #define NOBUG_CPP_DEFINE_FLAG(name) \
869 NOBUG_DEFINE_FLAG(name); \
870 static int nobug_##name##_cppinit##__LINE__ = NOBUG_INIT_FLAG(name)
872 #define NOBUG_CPP_DEFINE_FLAG_PARENT(name, parent) \
873 NOBUG_DEFINE_FLAG_PARENT(name, parent); \
874 static int nobug_##name##_cppinit##__LINE__ = NOBUG_INIT_FLAG(name)
876 #define NOBUG_CPP_DEFINE_FLAG_LIMIT(name, default) \
877 NOBUG_DEFINE_FLAG_LIMIT(name, default); \
878 static int nobug_##name##_cppinit##__LINE__ = NOBUG_INIT_FLAG_LIMIT(name, default)
880 #define NOBUG_CPP_DEFINE_FLAG_PARENT_LIMIT(name, parent, default) \
881 NOBUG_DEFINE_FLAG_PARENT_LIMIT(name, parent, default); \
882 static int nobug_##name##_cppinit##__LINE__ = NOBUG_INIT_FLAG_LIMIT(name, default)
885 #ifndef NOBUG_LOG_LIMIT_ALPHA
886 # define NOBUG_LOG_LIMIT_ALPHA LOG_INFO
888 #ifndef NOBUG_LOG_LIMIT_BETA
889 # define NOBUG_LOG_LIMIT_BETA LOG_WARNING
891 #ifndef NOBUG_LOG_LIMIT_RELEASE
892 # define NOBUG_LOG_LIMIT_RELEASE LOG_CRIT
895 #ifndef NOBUG_LOG_LIMIT
896 # define NOBUG_LOG_LIMIT \
898 NOBUG_LOG_LIMIT_ALPHA, \
899 NOBUG_LOG_LIMIT_BETA, \
900 NOBUG_LOG_LIMIT_RELEASE)
903 #ifndef NOBUG_LOG_TARGET_ALPHA
904 # define NOBUG_LOG_TARGET_ALPHA NOBUG_TARGET_CONSOLE
906 #ifndef NOBUG_LOG_TARGET_BETA
907 # define NOBUG_LOG_TARGET_BETA NOBUG_TARGET_FILE
909 #ifndef NOBUG_LOG_TARGET_RELEASE
910 # define NOBUG_LOG_TARGET_RELEASE NOBUG_TARGET_SYSLOG
913 #ifndef NOBUG_LOG_TARGET
914 # define NOBUG_LOG_TARGET \
916 NOBUG_LOG_TARGET_ALPHA, \
917 NOBUG_LOG_TARGET_BETA, \
918 NOBUG_LOG_TARGET_RELEASE)
921 #define NOBUG_SET_LIMIT(flag, min) \
923 NOBUG_FLAG(flag) = (min), \
924 NOBUG_FLAG(flag) = (min), \
929 short macros without NOBUG_
931 #ifndef NOBUG_DISABLE_SHORTNAMES
933 #define REQUIRE NOBUG_REQUIRE
936 #define REQUIRE_DBG NOBUG_REQUIRE_DBG
939 #define REQUIRE_IF NOBUG_REQUIRE_IF
941 #ifndef REQUIRE_IF_DBG
942 #define REQUIRE_IF_DBG NOBUG_REQUIRE_IF_DBG
945 #define ENSURE NOBUG_ENSURE
948 #define ENSURE_DBG NOBUG_ENSURE_DBG
951 #define ENSURE_IF NOBUG_ENSURE_IF
953 #ifndef ENSURE_IF_DBG
954 #define ENSURE_IF_DBG NOBUG_ENSURE_IF_DBG
957 #define ASSERT NOBUG_ASSERT
960 #define ASSERT_DBG NOBUG_ASSERT_DBG
963 #define ASSERT_IF NOBUG_ASSERT_IF
965 #ifndef ASSERT_IF_DBG
966 #define ASSERT_IF_DBG NOBUG_ASSERT_IF_DBG
969 #define INVARIANT NOBUG_INVARIANT
971 #ifndef INVARIANT_DBG
972 #define INVARIANT_DBG NOBUG_INVARIANT_DBG
975 #define INVARIANT_IF NOBUG_INVARIANT_IF
977 #ifndef INVARIANT_IF_DBG
978 #define INVARIANT_IF_DBG NOBUG_INVARIANT_IF_DBG
980 #ifndef INVARIANT_ASSERT
981 #define INVARIANT_ASSERT NOBUG_INVARIANT_ASSERT
984 #define DUMP NOBUG_DUMP
987 #define DUMP_DBG NOBUG_DUMP_DBG
990 #define DUMP_IF NOBUG_DUMP_IF
993 #define DUMP_IF_DBG NOBUG_DUMP_IF_DBG
996 #define DUMP_LOG NOBUG_DUMP_LOG
999 #define DUMP_LOG_DBG NOBUG_DUMP_LOG_DBG
1002 #define DUMP_LOG_IF NOBUG_DUMP_LOG_IF
1004 #ifndef DUMP_LOG_IF_DBG
1005 #define DUMP_LOG_IF_DBG NOBUG_DUMP_LOG_IF_DBG
1008 #define LOG NOBUG_LOG
1011 #define LOG_DBG NOBUG_LOG_DBG
1014 #define LOG_IF NOBUG_LOG_IF
1017 #define LOG_IF_DBG NOBUG_LOG_IF_DBG
1020 #define ERROR NOBUG_ERROR
1023 #define ERROR_DBG NOBUG_ERROR_DBG
1026 #define ERROR_IF NOBUG_ERROR_IF
1028 #ifndef ERROR_IF_DBG
1029 #define ERROR_IF_DBG NOBUG_ERROR_IF_DBG
1032 #define WARN NOBUG_WARN
1035 #define WARN_DBG NOBUG_WARN_DBG
1038 #define WARN_IF NOBUG_WARN_IF
1041 #define WARN_IF_DBG NOBUG_WARN_IF_DBG
1044 #define INFO NOBUG_INFO
1047 #define INFO_DBG NOBUG_INFO_DBG
1050 #define INFO_IF NOBUG_INFO_IF
1053 #define INFO_IF_DBG NOBUG_INFO_IF_DBG
1056 #define NOTICE NOBUG_NOTICE
1059 #define NOTICE_DBG NOBUG_NOTICE_DBG
1062 #define NOTICE_IF NOBUG_NOTICE_IF
1064 #ifndef NOTICE_IF_DBG
1065 #define NOTICE_IF_DBG NOBUG_NOTICE_IF_DBG
1068 #define TRACE NOBUG_TRACE
1071 #define TRACE_DBG NOBUG_TRACE_DBG
1074 #define TRACE_IF NOBUG_TRACE_IF
1076 #ifndef TRACE_IF_DBG
1077 #define TRACE_IF_DBG NOBUG_TRACE_IF_DBG
1080 #define BACKTRACE NOBUG_BACKTRACE
1082 #ifndef BACKTRACE_DBG
1083 #define BACKTRACE_DBG NOBUG_BACKTRACE_DBG
1086 #define DEPRECATED NOBUG_DEPRECATED
1088 #ifndef UNIMPLEMENTED
1089 #define UNIMPLEMENTED NOBUG_UNIMPLEMENTED
1092 #define FIXME NOBUG_FIXME
1095 #define TODO NOBUG_TODO
1098 #define PLANNED NOBUG_PLANNED
1101 #define NOTREACHED NOBUG_NOTREACHED
1104 #define CLEANUP NOBUG_CLEANUP
1107 #define CHECKED NOBUG_CHECKED
1110 #define UNCHECKED NOBUG_UNCHECKED
1112 #ifndef RESOURCE_ANNOUNCE
1113 #define RESOURCE_ANNOUNCE NOBUG_RESOURCE_ANNOUNCE
1115 #ifndef RESOURCE_FORGET
1116 #define RESOURCE_FORGET NOBUG_RESOURCE_FORGET
1118 #ifndef RESOURCE_ENTER
1119 #define RESOURCE_ENTER NOBUG_RESOURCE_ENTER
1121 #ifndef RESOURCE_STATE
1122 #define RESOURCE_STATE NOBUG_RESOURCE_STATE
1124 #ifndef RESOURCE_LEAVE
1125 #define RESOURCE_LEAVE NOBUG_RESOURCE_LEAVE
1127 #ifndef RESOURCE_LEAVE_LOOKUP
1128 #define RESOURCE_LEAVE_LOOKUP NOBUG_RESOURCE_LEAVE_LOOKUP
1130 #ifndef RESOURCE_HANDLE
1131 #define RESOURCE_HANDLE NOBUG_RESOURCE_HANDLE
1133 #endif /* NOBUG_DISABLE_SHORTNAMES */
1134 #endif /* NOBUG_LIBNOBUG_C */
1140 // branch prediction on bools
1142 #define NOBUG_EXPECT_FALSE(x) __builtin_expect(!!(x),0)
1144 #define NOBUG_EXPECT_FALSE(x) x
1147 #define NOBUG_IF(bool, ...) NOBUG_CAT(NOBUG_IF_,bool)(__VA_ARGS__)
1148 #define NOBUG_IF_1(...) __VA_ARGS__
1149 #define NOBUG_IF_0(...)
1151 #define NOBUG_IFNOT(bool, ...) NOBUG_CAT(NOBUG_IF_, NOBUG_NOT(bool))(__VA_ARGS__)
1153 #define NOBUG_NOT(bool) NOBUG_CAT(NOBUG_NOT_, bool)
1154 #define NOBUG_NOT_1 0
1155 #define NOBUG_NOT_0 1
1157 #define NOBUG_AND(a,b) NOBUG_CAT3(NOBUG_AND_, a, b)
1158 #define NOBUG_AND_00 0
1159 #define NOBUG_AND_01 0
1160 #define NOBUG_AND_10 0
1161 #define NOBUG_AND_11 1
1163 #define NOBUG_OR(a,b) NOBUG_CAT3(NOBUG_OR_, a, b)
1164 #define NOBUG_OR_00 0
1165 #define NOBUG_OR_01 1
1166 #define NOBUG_OR_10 1
1167 #define NOBUG_OR_11 1
1169 #define NOBUG_XOR(a,b) NOBUG_CAT( NOBUG_XOR_, NOBUG_CAT(a,b))
1170 #define NOBUG_XOR_00 0
1171 #define NOBUG_XOR_01 1
1172 #define NOBUG_XOR_10 1
1173 #define NOBUG_XOR_11 0
1175 #define NOBUG_CAT(a,b) NOBUG_CAT_(a,b)
1176 #define NOBUG_CAT_(a,b) a##b
1178 #define NOBUG_CAT3(a,b,c) NOBUG_CAT3_(a,b,c)
1179 #define NOBUG_CAT3_(a,b,c) a##b##c
1181 #define NOBUG_HEAD(head, ...) head
1182 #define NOBUG_TAIL(_, ...) , ## __VA_ARGS__
1184 #define NOBUG_STRINGIZE(s) NOBUG_STRINGIZE_(s)
1185 #define NOBUG_STRINGIZE_(s) #s
1189 LIBNOBUG DECLARATIONS
1198 enum nobug_log_targets
1200 NOBUG_TARGET_RINGBUFFER
,
1201 NOBUG_TARGET_CONSOLE
,
1203 NOBUG_TARGET_SYSLOG
,
1204 NOBUG_TARGET_APPLICATION
1210 struct nobug_flag
* parent
;
1213 struct nobug_ringbuffer
* ringbuffer_target
;
1214 FILE* console_target
;
1219 nobug_env_parse_flag (const char* env
, struct nobug_flag
* flag
, int default_target
, int default_limit
);
1222 nobug_env_init_flag (struct nobug_flag
* flag
, int default_target
, int default_limit
);
1228 struct nobug_ringbuffer
1237 enum nobug_ringbuffer_flags
1239 NOBUG_RINGBUFFER_DEFAULT
, /* Default is to overwrite file and delete it on nobug_ringbuffer_destroy */
1240 NOBUG_RINGBUFFER_APPEND
= 1, /* use existing backing file, append if possible */
1241 NOBUG_RINGBUFFER_TEMP
= 2, /* unlink file instantly */
1242 NOBUG_RINGBUFFER_KEEP
= 4 /* dont unlink the file at destroy */
1246 Note: some flags conflict (TEMP with KEEP) nobug_ringbuffer will not error on these but continue gracefully
1247 with sane (but undefined) semantics.
1249 struct nobug_ringbuffer
*
1250 nobug_ringbuffer_init (struct nobug_ringbuffer
* self
, size_t size
,
1251 const char * name
, int flags
);
1253 struct nobug_ringbuffer
*
1254 nobug_ringbuffer_new (size_t size
, const char * name
, int flags
);
1256 struct nobug_ringbuffer
*
1257 nobug_ringbuffer_destroy (struct nobug_ringbuffer
* self
);
1260 nobug_ringbuffer_delete (struct nobug_ringbuffer
* self
);
1263 nobug_ringbuffer_vprintf (struct nobug_ringbuffer
* self
, const char* fmt
, va_list ap
);
1266 nobug_ringbuffer_printf (struct nobug_ringbuffer
* self
, const char* fmt
, ...);
1269 nobug_ringbuffer_prev (struct nobug_ringbuffer
* self
, char* pos
);
1272 nobug_ringbuffer_next (struct nobug_ringbuffer
* self
, char* pos
);
1275 nobug_ringbuffer_save (struct nobug_ringbuffer
* self
, FILE* out
);
1278 nobug_ringbuffer_load (struct nobug_ringbuffer
* self
, FILE* in
);
1281 nobug_ringbuffer_pos (struct nobug_ringbuffer
* self
);
1284 nobug_ringbuffer_pop (struct nobug_ringbuffer
* self
);
1288 multithreading extras
1290 #if NOBUG_USE_PTHREAD
1292 struct nobug_tls_data
1294 const char * thread_id
;
1295 struct nobug_resource_record
* lock_stack
;
1298 extern pthread_key_t nobug_tls_key
;
1301 nobug_thread_id_set (const char* name
);
1304 nobug_thread_id_get (void);
1306 extern pthread_mutex_t nobug_global_mutex
;
1307 #define NOBUG_LOCK pthread_mutex_lock (&nobug_global_mutex)
1308 #define NOBUG_UNLOCK pthread_mutex_unlock (&nobug_global_mutex)
1311 #define NOBUG_UNLOCK
1318 struct nobug_resource_record
1320 const char* type
; /* type or state */
1321 const char* name
; /* name */
1322 void* object_id
; /* unique identifer, usually a this pointer or similar */
1323 void* data
; /* tree of holders in resouces, backpointer to resource in holders */
1324 const char* extra
; /* extra information, file/line usually */
1325 unsigned long counter
; /* users or recursive enters */
1326 #if NOBUG_USE_PTHREAD
1327 const char* thread_id
;
1328 struct nobug_resource_record
* link
; /* used by the deadlock detector */
1332 enum nobug_resource_state
1334 NOBUG_RESOURCE_WAITING
,
1335 //NOBUG_RESOURCE_TRYING,
1336 NOBUG_RESOURCE_EXCLUSIVE
,
1337 NOBUG_RESOURCE_RECURSIVE
1340 extern void* nobug_resource_registry
;
1341 extern FILE* nobug_resource_dump_target
;
1343 extern const char* nobug_resource_error
;
1345 extern const char* nobug_resource_states
[];
1349 struct nobug_resource_record
*
1350 nobug_resource_announce (const char* type
, const char* name
, const void* object_id
, const char* extra
);
1353 nobug_resource_forget (struct nobug_resource_record
* node
);
1355 struct nobug_resource_record
*
1356 nobug_resource_find (const struct nobug_resource_record
* resource
, const void* object_id
);
1358 struct nobug_resource_record
*
1359 nobug_resource_enter (struct nobug_resource_record
* resource
,
1361 const void* object_id
,
1362 enum nobug_resource_state state
,
1366 nobug_resource_state (struct nobug_resource_record
* resource
,
1367 enum nobug_resource_state state
);
1370 nobug_resource_leave (struct nobug_resource_record
* handle
);
1373 nobug_resource_dump (struct nobug_resource_record
* resource
, FILE* target
);
1376 nobug_resource_dump_all (FILE* target
);
1379 nobug_resource_dump_resources (FILE* target
);
1383 global config, data and defaults
1385 extern const char* nobug_resource_acquired
;
1390 nobug_log (struct nobug_flag
* flag
, int lvl
, const char* fmt
, ...);
1392 typedef void (*nobug_application_cb
)(struct nobug_flag
* flag
, int priority
, const char *log
, void* data
);
1394 extern struct nobug_ringbuffer nobug_default_ringbuffer
;
1395 extern FILE* nobug_default_file
;
1396 extern struct nobug_flag nobug_flag_NOBUG_ON
;
1397 extern unsigned long long nobug_counter
;
1398 extern nobug_application_cb nobug_callback
;
1399 extern void* nobug_callback_data
;
1405 #ifndef NOBUG_LIBNOBUG_C
1408 tag this translation unit as unchecked in ALPHA and BETA builds
1410 NOBUG_IF_NOT_RELEASE(NOBUG_UNCHECKED
);
1412 #endif /* NOBUG_LIBNOBUG_C */