3 Christian_Thäter,_Benny_Lyons
5 // doc/overview.txt:1 //
7 Everyone makes mistakes, but with NoBug you won't make them twice!
10 Nobug is a debugging library for instrumenting C and C++ programs
11 inspired by ideas originating from Design-by-Contract.
16 The following features are provided by NoBug:
18 * Three different check levels: from detailed to final no-overhead
19 * Scope tags: tell whenever a function or loop is considered to be bug free
20 * Precondition, Postcondition and Invariant checks and generic assertions
21 * Debugger support (actions are only executed while running under a
22 debugger), currently only valgrind is supported
23 * Data structures can be dumped
24 * Application activities can be logged
25 * Runtime customizable logging via an environment variable
26 * Different logging targets to stderr, syslog, debugger, ...
27 * Annotation of your sourcecode about known bugs, things to do, etc.
28 * Tracking resources (files, locks, etc.) used by your program; help in
30 * Detecting potential deadlocks
31 * Simulate errors by injecting faults
32 * Additionally, the NoBug project is used to maintain a script and
33 some tools to setup testsuites
35 In contrast to traditional debuggers, NoBug is a non-interactive debugger which
36 is linked to your application doing hard-coded tests in an efficient,
39 .What NoBug can not do
41 NoBug is a (macro-)library, it is not a C/C++ language extension. This
42 means that code must be called at runtime to benefit from the set up
43 contracts. Whats not tested is likely slipping through the net. Being
44 part of the program itself it is affected by memory corruption,
45 certain kinds of misuse may introduce new bugs (test expressions with
46 side effectsfor example).
48 // doc/buildinstall.txt:1 //
49 Building and Installing
50 -----------------------
55 NoBug has been developed on linux, using gcc. It should be possible to port
56 it to any other POSIX compliant operating system. Most platform
57 specific things are kept optional, but some things need to be
58 rewritten for the target platform. Currently Linux with a gcc that conforms to
59 C99 is supported for both 32 and 64 bit architectures.
60 One gcc extentsion that is used (token pasting of varadic macros) may prevent
61 portability to other compilers as some compilers don't support such extensions.
64 `-------`---------------`---------------`--------------------------------------
66 -------------------------------------------------------------------------------
67 x86_64 Debian supported Reference Platform
68 x86 other Linux supported Please report distro specific problems
69 armel maemo5 supported check fails in SDK (emulator bug)
70 x86* MacOS X should work Please test
71 x86 OpenSolaris mostly Builds, but target check fails
72 *BSD planned Need volunteer for testing
73 -------------------------------------------------------------------------------
75 NoBug has no mandatory dependencies on other software and libraries,
76 some things such as valgrind support are optional and should be automatially
77 detected during the build, i.e., when ./configure is called.
83 Releases are available on:
84 http://www.pipapo.org/nobug-releases/
86 Gpg signed tarballs are being used for distribution. The first step involves
87 checking the signature:
89 $ gpg nobug-VERSION.tar.gz.gpg
91 This will produce a nobug-VERSION.tar.gz and report if the signature could be
94 Since they are built with gnu autotools, the usual build and install procedure
97 $ tar xzvf nobug-VERSION.tar.gz
103 $ make check # optional, run the testsuite
104 $ make install # depending on distribution and setup, do this as root
107 Development Version via git
108 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
109 You can obtain a development version by using git. The git repository can be
111 `git://git.pipapo.org/nobug` or mirrored at repo.or.cz
112 `git://repo.or.cz/nobug.git`.
114 Clone the git repository by:
116 $ git clone git://git.pipapo.org/nobug
118 After cloning the repository, then bootstrap the autotools:
121 $ autoreconf -i # creates the configure file
123 Then the usual `cd build && ../configure && make && make install` (as above) will work.
124 Careful users may run `make check` to run a testsuite before installing.
127 Keeping Git Up To Date
128 ^^^^^^^^^^^^^^^^^^^^^^
130 To update to any new revision, just enter the nobug dir and
134 After that you can build as above (cd build && ../configure && make && make install).
135 This default pull will update from the 'master' branch which is meant to be an on-going
136 stable version (latest release + bugfixes).
141 Currently, NoBug installs the following:
143 * A single nobug.h headerfile. Include this in your code.
144 * Static libraries. Statically link these to your application:
145 - `libnobug.a` for singlethreaded programs.
146 - `libnobugmt.a` for multithreaded programs.
147 * Dynamic Libraries. Dynamically link these to your application:
148 - `libnobug.so` for singlethreaded programs.
149 - `libnobugmt.so` for multithreaded programs.
150 - associated libtool descriptors (`libnobug*.la`)
151 * Pkgconfig control files:
152 - `nobug.pc` for singlethreaded programs.
153 - `nobugmt.pc` for multithreaded programs.
154 * The `nobug_rbdump` utility to inspect NoBug ringbuffers.
157 .Generating This Documentation
159 $ make nobug_manual.txt
160 $ ascidoc -a toc nobug_manual.txt
162 // doc/using.txt:1 //
166 Your application will have to include the header file 'nobug.h' before NoBug
172 Once you've included the NoBug API in your application, you'll then have to select
173 a 'build-level'. Build-levels are discussed later, c.f.,
174 xref:buildlevel[buildlevel]. Build-levels are used to define the amount of
175 information NoBug provides to you. Maximum information is generally required while
176 developing an application and the ALPHA build-level is most apropriate during
177 this phase; whereas the released phase of an application will usually only require
178 sparse information, for which the RELEASE build-level has been conceived.
180 A build-level must always be specified, otherwise the compiler will complain
181 while attempting to compile your application. You can specifiy a build level in
182 one of two ways: use a define statement in one of your modules, or pass the
183 build-level using the -D flag to your compiler. Assuming we'd like to select
184 the ALPHA build-level in your application, then your module would assume the
193 Subsequently you'll have to link the appropriate library to your application.
195 A number of different libraries are available to link depending on whether you
196 require to statically or dynamically link, or whether your application is multi
197 or single threaded. The link order is important on your link line. Link the NoBug
198 library 'after' your application's modules. Here's how to statically link,
199 single-threaded applications:
203 gcc -o mybinary $(WHATEVER_FLAGS) mymodule1.o ... mymodulen.o ..../libs/libnobug.a
206 However, for more flexibility in selecting a build-level, you might wish to
207 define various targets in your makefile, one for each build-level. In such
208 cases, the -D flag in your makefile is most appropriate; so your link line for
209 an ALPHA build with multi-threaded support would look like the following:
213 gcc -o mybinary -DEBUG_ALPHA $(WHATEVER_FLAGS) mymodule1.o ... mymodulen.o ..../libs/libnobugmt.a
216 Both libraries must be initialised before they can be used. There are a number
217 of different ways to initialise the NoBug libraries. One of the easiest ways
218 to initialise the NoBug libraries is to use the `NOBUG_INIT` macro, which must
219 be used before any features can be used or any thread is created. This is
220 discussed in more detail in the xref:multithreading[multithreading] chapter.
222 So putting all this together, our application using NoBug might look something
228 #include "nobug.h" /* Include the NoBug API */
229 #define EBUG_ALPHA /* If we have not used the -D Flag in our makefile */
233 NOBUG_INIT; /* Initialise NoBug libs */
244 Many aspects of NoBug can be configured by overriding macros before 'nobug.h' is
247 A project using NoBug can use autoconf to check for execinfo and
250 AC_CHECK_HEADER([execinfo.h], AC_DEFINE(HAVE_EXECINFO_H))
251 PKG_HAVE_DEFINE_WITH_MODULES(VALGRIND, [valgrind])
253 For Multithreaded programs, you should also check for the availability of pthreads
258 When the resulting `HAVE_PTHREAD`, `HAVE_EXECINFO_H` and
259 `HAVE_VALGRIND_H` are defined by the configure script, the
260 relevant features become available.
262 NoBug then defines `NOBUG_USE_PTHREAD`, `NOBUG_USE_VALGRIND` and
263 `NOBUG_USE_EXECINFO` to 1. If you do not want to use any of these features in
264 NoBug, you can override these macros by setting to 0 before including nobug.h.
266 If `NVALGRIND` is defined, there will be no support for valgrind.
270 There are many other macros which can be set and overridden by the user to
271 control behavior. Your help would be appreciated in expanding this documentation
272 if you find some features useful; or simply contact any of the authors.
276 .Using Nobug from a Project using autoconf
279 PKG_CHECK_MODULES(NOBUGMT_LUMIERA, [nobugmt >= 0.3rc1],
280 AC_DEFINE(HAVE_NOBUGMT_H),
281 AC_MSG_ERROR([NoBug pkg-config metadata missing])
285 // doc/additional.txt:1 //
286 Checking for Additional Tools
287 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
289 Various peripheral tools can be used by NoBug depending on the requirements
290 of the application and the detail desired by the user. Such tools can provide
291 additional, detailed information on the application and its behaviour.
292 However, some applications may not require such detail and the associated
293 overhead in information, and users may decide to omit excess information by
294 excluding such tools.
296 At the moment NoBug supports the optional inclusion of gdb, valgrind and support
297 for multi-threaded applications and the information that can be provided by
298 these tools. However, support for other tools may be supplied in the future,
299 e.g. the dbx debugger on OpenSolaris.
301 Such tools can be easily queried on the system and if they are available on a
302 particular system, they can be used by NoBug to provide even more information on
303 the application using NoBug. If such tools are not available or are not
304 required by the user for one reason or other, then NoBug will happily function
305 as usual, just without the extra information.
307 Testing the availability of such tools on a particular system can be achieved
308 using autoconf, as illustrated in the following:
310 `*NOBUG_USE_VALGRIND*`::
312 `0`:: Do not use valgrind
314 `*NOBUG_USE_PTHREAD*`::
315 `1`:: Support for multi-thread applications
316 `0`:: Single-threaded applications
318 `*NOBUG_USE_EXECINFO*`::
319 `1`:: Backtrace information
320 `0`:: No backtrace information
322 These macros are then automatically defined when the configuration system
323 provides the associated `HAVE_*` macros, but can then be overridden by the user,
324 depending on the user's requirements.
327 // doc/whichlibrary.txt:1 //
328 Link Appropriate Library
329 ~~~~~~~~~~~~~~~~~~~~~~~~
331 Finally, the appropriate library (for either single or multi-threaded
332 applications) is linked to the project.
334 *libnobug*:: Link-in this library for single threaded applications.
335 *libnobugmt*:: Link with this library for multi-threaded applications.
337 NoBug installed static and dynamic libraries. When your application
338 uses multiple dynamic libraries which use NoBug or you build a dynamic
339 library, then you have to link against the dynamic library.
341 You can use the `pkg-config` tool to gather information about NoBug in
344 Release builds remove all assertions, but logging is still kept. We
345 make the assumption that bugs which were not covered in alpha and beta
346 builds will not easily show up in releases because the assertions
347 there were not sufficient. Furthermore, end users are not test bunnies
348 and will not provide good bug reports anyway. If there is a problem in
349 a release build, try to track down the cause using a beta build from
352 // doc/initialization.txt:1 //
359 Before anything from NoBug can be used, NoBug must be initialised. This is
360 performed by calling one of the `NOBUG_INIT_` macros.
362 The simpliest such macro among the initialising set is the following:
366 `NOBUG_INIT` can be called more than once, subsequent calls will be a no-op,
367 thus initialising in main and in libraries won't interfere with one another.
369 In other words, `NOBUG_INIT` is usually the first call to NoBug.
372 Since NoBug is intended to be available throughout its whole lifetime,
373 destroying it is not to be advised. Nevertheless, there is a destroy function
374 void nobug_destroy (void)
376 to shutdown NoBug, and this frees all resources associated with it.
377 This is mostly used in the NoBug testsuite itself to check for leaks,
378 and it might be useful for other programs which employ some kind of
384 If you want to use environment variable controlled debuging, then you have to
385 initialize each defined flag with
387 NOBUG_INIT_FLAG(flagname)
391 NOBUG_INIT_FLAG_LIMIT(flagname, default)
393 or one of the C++ compatibility macros.
395 This is documented later in the xref:logconfig[logging configuration] chapter.
400 In Multithreaded programs you should assign an identifier to each
401 thread. A thread identifier is a string which will be automatically
402 appended with an underscore and a incrementing integer. It is is created with:
404 NOBUG_THREAD_ID_SET(name)
406 Calling `NOBUG_THREAD_ID_SET("worker")` will yield in a thread
407 identifier 'worker_1' for example.
409 If you don't set an identifier, then NoBug will assign an automatic one.
410 This is further documented in the xref:multithreading[multi threading]
411 section of this manual.
416 -------------------------------------------------------
418 NOBUG_DEFINE_FLAG(example);
425 NOBUG_THREAD_ID_SET("main");
426 NOBUG_INIT_FLAG(example);
430 -------------------------------------------------------
432 // doc/buildlevels.txt:1 //
434 Debugging Information Granuality: The Build Levels
435 --------------------------------------------------
437 There are three different levels of debugging information available: alpha, beta
438 and release. One of these levels must be specified before compiling, otherwise
439 an error while compiling will occur.
443 This debugging level is envisaged for the development phase of a project
444 where exhaustive testing and logging are required.
446 This debugging level is more appropriate for projects beyond the
447 development phase and ready for trials in the field and users willing to
450 This level is for final, end-users.
452 .Select a Build Level
453 A logging level can be selected by either using a define in one of the
454 applications' modules, or by passing the appropriate level using the -D switch
457 *ALPHA*:: -DEBUG_ALPHA (`#define EBUG_ALPHA`)
459 *BETA*:: -DEBUG_BETA (`#define EBUG_BETA`)
461 *RELEASE*:: -DNDEBUG (`#define NDEBUG`)
463 If none of the above switches has been set, NoBug will abort the
464 compilation with an error.
466 // doc/logging.txt:1 //
470 Nearly all NoBug Macros emit some log message. NoBug gives the user fine
471 grained control over these log messages to display only interesting information
472 without loosing details.
474 Log messages can be routed to various destinations. The following destintaions
478 The underlying storage backend. Messages are appended to the
479 end of the buffer, overwriting older messages at the front of
480 the buffer. NoBug comes with a highly efficient ringbuffer
481 implementation. This ringbuffer is temporary by default but
482 can be made persistent on disk which can be inspected with the
486 This is either just stderr, or, if running under a supported
487 debugger, the debuggers facilities to print messages will be used.
490 The user can open files for log messages.
493 Messages are sent to the standard system logging daemon.
496 There are hooks which allow the programmer to catch logmessages and
497 display them in an application which are defined by the application.
499 Each logmessage has a priority describing its severity in the same way as
502 All non-fatal messages are associated with a programmer defined flag describing
503 the source of the message (subsystem, module, ...).
505 Putting this all together: A user can define which source/flag will be logged at
506 what priority level and to which destination. To make this all easier, NoBug
507 tries to provide reasonable defaults.
509 // doc/logconfiguration.txt:1 //
516 Each log macro has an explicit or implicit log-level which
517 correspondends to syslog levels. Logging is only emitted when the
518 message is more severe or the same as a defined limit.
521 .Default levels for logging
523 `````~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
524 , ALPHA, BETA , RELEASE,
525 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
526 *ringbuffer* , TRACE, INFO , NOTICE , ringbuffer must always be most verbose
527 *console* , INFO , NOTICE , -1 , no log to console in release
528 *file* , TRACE, NOTICE , WARNING,
529 *syslog* , -1 , NOTICE , WARNING, no syslog for test runs
530 *application*, INFO , WARNING, ERROR ,
531 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
533 Depending on the build level, there is a default logging target and a default
534 limit which is selected when the user doesn't specify one.
536 The following default limits are available:
538 * In *ALPHA* builds, `NOBUG_LOG_LIMIT_ALPHA` is used which defaults to `LOG_INFO`
539 * In *BETA* builds, `NOBUG_LOG_LIMIT_BETA` is used and defaults to `LOG_WARNING`
540 * In *RELEASE* builds, `NOBUG_LOG_LIMIT_RELEASE` is used and defaults to `LOG_CRIT`
542 The default targets are:
544 * In *ALPHA* builds, `NOBUG_LOG_TARGET_ALPHA` is used which defaults to
545 `NOBUG_TARGET_CONSOLE`
546 * In *BETA* builds, `NOBUG_LOG_TARGET_BETA` is used and defaults to
548 * In *RELEASE* builds, `NOBUG_LOG_TARGET_RELEASE` is used and defaults to
549 `NOBUG_TARGET_SYSLOG`
552 You can override all these values with your own values. As an alternative,
553 `NOBUG_LOG_LIMIT` and `NOBUG_LOG_TARGET` can be defined before
554 including "nobug.h" to override all defaults.
556 // doc/logflags.txt:1 //
561 Flags are used to inform NoBug about subsystems/modules or even finer
562 grained sections of the code. These are referred to as 'channels' in other
565 A flag should be declared in a headerfile using the following mechanism:
568 NOBUG_DECLARE_FLAG(flagname)
570 It is advisable to do so in one of your header files.
572 Furthermore, the flag must be defined in some implementation file by using one
573 of the following schemes:
576 NOBUG_DEFINE_FLAG(flagname)
580 [[DEFINE_FLAG_LIMIT]]
581 NOBUG_DEFINE_FLAG_LIMIT(flagname, limit)
583 Moreover, macros are available that accept a 'parent' flag as a parameter, which is then
584 used to initialize the defaults from another flag:
586 [[DEFINE_FLAG_PARENT]]
587 NOBUG_DEFINE_FLAG_PARENT(flagname, parent)
591 [[DEFINE_FLAG_PARENT_LIMIT]]
592 NOBUG_DEFINE_FLAG_PARENT_LIMIT(flagname, parent, limit)
594 This can be used to create hierachies of flags
597 [[Cplusplus_logflags]]
598 .C++ support, C++ logflags
600 Additional macros are available for applications written in C++:
602 NOBUG_CPP_DEFINE_FLAG(name)
603 NOBUG_CPP_DEFINE_FLAG_PARENT(name, parent)
604 NOBUG_CPP_DEFINE_FLAG_LIMIT(name, default)
605 NOBUG_CPP_DEFINE_FLAG_PARENT_LIMIT(name, parent, default)
607 These macros statically initialize the flags when they are defined, there is no
608 need to call `NOBUG_INIT_FLAG()` (see below).
611 .Force declarations only
613 When the the following preprocessor constant is defined to be `1`:
618 then *all* definitions here (`NOBUG_DEFINE_*`)
619 become declarations only. When this is defined to be `0` (which is the
620 default) then all definitions behave as described.
621 This can be used to construct a headerfile which only contains
622 definitions, but, by default, yield only declarations. This provides one
623 convenient single point to maintain flag configurations.
625 .Maintaining flags in a single header 'flags.h'
631 if not included from flags.c then declare the flags,
635 #define NOBUG_DECLARE_ONLY 1
638 /* use only DEFINE_FLAG here */
639 NOBUG_DEFINE_FLAG(example);
642 Reset it to 0 to cause no trouble
645 #undef NOBUG_DECLARE_ONLY
646 #define NOBUG_DECLARE_ONLY 0
659 .Logging Flag Initialization
663 NOBUG_INIT_FLAG(flagname)
667 NOBUG_INIT_FLAG_LIMIT(flagname, default)
669 once at the start of your program for each flag.
671 For flags defined with `NOBUG_DEFINE_FLAG(flagname)` the defaults are initialized
672 as in the xref:logdefaults[table above], while
673 `NOBUG_DEFINE_FLAG_LIMIT(flagname, level)` is used to initialize the
674 default target (depending on build level) to `level`.
676 // doc/logflagsenv.txt:1 //
678 Control what gets logged
679 ~~~~~~~~~~~~~~~~~~~~~~~~
681 The `NOBUG_INIT_FLAG...` calls parsing the environment variable
682 'NOBUG_LOG' to configure what gets logged at runtime. The syntax is as
685 .Formal Syntax for log control
688 logdecl_list --> logdecl, any( ',' logdecl_list).
690 logdecl --> flag, opt(limitdecl, any(targetdecl)).
692 flag --> "identifier of a flag".
694 limitdecl --> ':', "LIMITNAME".
696 targetdecl --> '@', "targetname", opt(targetopts).
698 targetopts --> '(', "options for target", ')', opt(targetopts).
701 Roughly speaking, 'NOBUG_LOG' contains a comma separated list of declarations for
702 flags which are the name of the flag followed by a limit which is written in
703 all uppercase letters and preceeded by a colon, followed by target declarations
704 which are names of the targets, introduced by a at sign. Target declarations
705 can have option, described in the next section. Limit and target
706 declarations are optional and then choosen from the defaults table above. These
707 defaults are currently just an guess what should be useable and might be
712 The Following options are available:
715 `(file=_filename_)`:: set filename backing the ringbuffer
716 `(size=_nnn_)`:: set size of the ringbuffer
717 `(append)`:: don't erase existing ringbuffer
718 `(keep)`:: keep file after application end
719 `(temp)`:: unlink file instantly at creation
722 `(fd=n)`:: redirect console output to fd n
725 `(name=_filename_)`:: log to filename
726 `(append)`:: append to (existing) log
729 `(ident=_name_)`:: global prefix for syslog
730 `(cons)`:: log to system console if syslog is down
731 `(pid)`:: include pid in log
732 `(perror)`:: log to stderr as well
735 .How the NOBUG_LOG is used
738 # set the limit of the default target a default limit (see table above)
739 NOBUG_LOG='flag,other'
741 # set the limit of the default target to DEBUG
742 NOBUG_LOG='flag:DEBUG'
744 # set console and syslog limits for flag to DEBUG
745 NOBUG_LOG='flag:DEBUG@console@syslog'
747 # trace 'other' to a persistent ringbuffer
748 NOBUG_LOG='other:TRACE@ringbuffer(file=log.rb)(size=8192)(keep)'
751 .Using log flags (example.c)
756 NOBUG_DEFINE_FLAG (test);
760 /* NOBUG_INIT; // not needed because of NOBUG_INIT_FLAG */
761 NOBUG_INIT_FLAG (test);
763 TRACE (test, "Logging enabled");
764 TRACE (NOBUG_ON, "Always on");
771 $ cc -DEBUG_ALPHA -lnobug example.c
773 0000000002: TRACE: example.c:11: main: Always on
775 $ NOBUG_LOG=test:TRACE ./a.out
776 0000000001: TRACE: example.c:10: main: Logging enabled
777 0000000002: TRACE: example.c:11: main: Always on
784 There are some debugging flags which are predefined by NoBug.
789 The flag `NOBUG_ON` is always enabled at LOG_DEBUG level. This is
790 static and can not be changed.
795 The flag `NOBUG_ANN` is used for the source annotations. This is
796 static and can not be changed. It differs from `NOBUG_ON` as in
797 never logging to syslog and only define a LOG_WARNING limit for the
798 application callback.
803 Actions on NoBug itself will be logged under the `nobug` flag itself.
804 When you want to see whats going on (useful to check if you call
805 `NOBUG_INIT_FLAG()` on all flags) you can enable it with `NOBUG_LOG=nobug:TRACE`.
807 // doc/macros.txt:1 //
811 The NoBug interface is almost completely implemented using
812 preprocessor macros. This is required because NoBug uses the
813 `+++__FILE__+++` and `+++__LINE__+++` macros to log information on the
814 current file and the current line number within that file. Moreover,
815 all the flat namespace uppercase identifiers make it ease to recognise
816 the macros in source code.
818 All macros are available without condition with a `NOBUG_...` prefix.
819 Macros are also available without this prefix as a convenience,
820 however macros without this prefix must not have been previously
821 defined. When `NOBUG_DISABLE_SHORTNAMES` is defined before including
822 'nobug.h', then only the `NOBUG_` prefixed macros are available and
823 the short forms will never be defined.
825 All assertion and logging macros have a corresponding form
826 postfixed by `..._DBG`. Such macros will only be active within a
829 A set of macros are provided by NoBug that are postfixed by `..._IF`.
830 These macros have the following form:
832 * `..._IF(when, ...)`
834 They perform the desired action only if `when` is true. For example:
836 * `REQUIRE_IF(foo != NULL, foo->something == constrained)`
838 The assertion will only be performed if `foo` is non `NULL`.
840 Debugger versions are available using `..._IF_DBG` postfixed to the name
843 // doc/parametertable.txt:1 //
847 We use names for parameters which describe their type. These names are
848 orthogonal through all macro definitions.
851 `---------`------------------------------------------------------------------
852 `when` Assertion is only performed if expression `when` is true at runtime
853 `expr` Test without side effects
854 `fmt` printf-like format string
855 `...` If not preceded by `fmt`, then printf-like format string followed by its arguments; otherwise, only its arguments
856 `flag` Flag to enable custom logging groups
857 `type` Data type to be checked as a single identifier name
858 `pointer` Pointer to type
860 `depth` Depth for invariants and dumps
861 ---------------------------------------------------------------------------
863 // src/nobug.h:102 //
870 CHECK_IF(when, expr, ...)
872 This assertion is never optimized out. Its main purpose is for implementing
873 testsuites where one want to assert tests independent of the build level
878 REQUIRE_DBG(expr, ...)
879 REQUIRE_IF(when, expr, ...)
880 REQUIRE_IF_DBG(when, expr, ...)
882 Precondition (input) check. Use these macros to validate input a
883 function receives. The checks are enabled in *ALPHA* and *BETA* builds and
884 optimized out in *RELEASE* builds.
889 ENSURE_DBG(expr, ...)
890 ENSURE_IF(when, expr, ...)
891 ENSURE_IF_DBG(when, expr, ...)
893 Postcondition (progress/output) check. Use these macros to validate the
894 data a function produces (example: return value). The checks enabled
895 unconditionally in *ALPHA* builds and optimized out in *BETA* builds for
896 scopes which are tagged as `CHECKED`. In *RELEASE* builds this checks are
897 always optimized out, but scopes tagged as `UNCHECKED` are not permitted.
902 ASSERT_DBG(expr, ...)
903 ASSERT_IF(when, expr, ...)
904 ASSERT_IF_DBG(when, expr, ...)
906 Generic check. Use these macros when you want to validate something
907 which doesn't fall into one of the above categories. A example is when
908 a library function can return a unexpected result (scanf with syntax
909 error in the formatstring, when a constant/literal formatstring is
910 expected). The checks are enabled in *ALPHA* and *BETA* builds and
911 optimized out in *RELEASE* builds.
917 NoBug overrides the standard assert macro in *ALPHA* and *BETA* builds.
918 This is just a compatibility feature, its use is not suggested.
922 INVARIANT(type, pointer, depth)
923 INVARIANT_DBG(type, pointer, depth)
924 INVARIANT_IF(when,type, pointer, depth)
925 INVARIANT_IF_DBG(when, type, pointer, depth)
927 Checking invariants. You can provide more complex checking functions
928 which test the validity of datastructures. Invariants are only enabled
929 in *ALPHA* builds for scopes which are not tagged as `CHECKED` and
930 otherwise optimized out.
932 TODO: describe how to create invariant checks
934 // src/nobug.h:405 //
942 Never optimized out, logs at LOG_NOTICE level. Its main purpose is for implementing
943 testsuites where one want to print and log messages independent of the build level
949 ALERT_IF(when, flag, ...)
950 ALERT_IF_DBG(when, flag, ...)
952 This is the most critical condition an application might log. This might be used
953 if an error occurs which can not be handled except a safe shutdown for example.
958 CRITICAL_DBG(flag, ...)
959 CRITICAL_IF(when, flag, ...)
960 CRITICAL_IF_DBG(when, flag, ...)
962 An error which can not be handled occured but the application does not need to be
963 shutdowen, perhaps waiting for an operator to fix the cause.
967 ERROR(flag, fmt, ...)
968 ERROR_DBG(flag, fmt, ...)
969 ERROR_IF(when, flag, fmt, ...)
970 ERROR_IF_DBG(when, flag, fmt, ...)
972 Application takes a error handling brach
977 WARN_DBG(flag, fmt, ...)
978 WARN_IF(when, flag, fmt, ...)
979 WARN_IF_DBG(when, flag, fmt, ...)
981 Rare, handled but unexpected branch
986 INFO_DBG(flag, fmt, ...)
987 INFO_IF(when, flag, fmt, ...)
988 INFO_IF_DBG(when, flag, fmt, ...)
990 Message about program progress
994 NOTICE(flag, fmt, ...)
995 NOTICE_DBG(flag, fmt, ...)
996 NOTICE_IF(when, flag, fmt, ...)
997 NOTICE_IF_DBG(when, flag, fmt, ...)
999 More detailed progress message
1003 TRACE(flag, fmt, ...)
1004 TRACE_DBG(flag, fmt, ...)
1005 TRACE_IF(when, flag, fmt, ...)
1006 TRACEIF_DBG(when, flag, fmt, ...)
1008 Very fine grained messages
1010 NOTE: that `TRACE` corresponds to `LOG_DEBUG`, because using `DEBUG` could be ambiguous.
1014 LOG(flag, lvl, fmt, ...)
1015 LOG_DBG(flag, lvl, fmt, ...)
1016 LOG_IF(when, flag, lvl, fmt, ...)
1017 LOG_IF_DBG(when, flag, lvl, fmt, ...)
1019 Generic logging macro which takes the level explicitly,
1020 avoid this, unless you implement your own logging facilities.
1024 NOBUG_LOG_BASELIMIT_ALPHA
1025 NOBUG_LOG_BASELIMIT_BETA
1026 NOBUG_LOG_BASELIMIT_RELEASE
1029 anything more detailed than this base limits will be optimized out.
1030 This is used to reduce the logging overhead for *RELEASE* builds.
1031 By default the limit is set to `LOG_DEBUG` for *ALPHA* and *BETA*
1032 builds, so all logging is retained and `LOG_NOTICE` in *RELEASE*
1033 builds to log the application progress only coarsely then.
1035 This macros can be defined before including 'nobug.h' to some other
1036 log level (as defined in 'syslog.h').
1038 NOTE: there is no logging macro for `LOG_EMERG` since this is used by the assertions as fatal message
1040 // doc/dumping.txt:1 //
1042 Dumping Datastructures
1043 ----------------------
1045 How to write DUMP handlers
1047 One can write functions for dumping complex datastructures using the NoBug
1048 facilities. This is done by writing a custom function for each
1049 datastructure to be dumped which may recursively call other dumping
1050 functions. There are macros for logging within such a dumper function
1051 and for initiating a dump of a given datastructure.
1053 // src/nobug.h:320 //
1056 DUMP(flag, type, pointer, depth)
1057 DUMP_IF(when, flag, type, pointer, depth)
1059 This macros call a datastructure dump of the object (`pointer`) in question.
1060 `DUMP_IF` is the only enabled dumping macro for the RELEASE build level.
1065 DUMP_LOG_DBG(fmt, ...)
1066 DUMP_LOG_IF(when, fmt, ...)
1067 DUMP_LOG_IF_DBG(when, fmt, ...)
1069 Any output from `DUMP` handlers should be done by these macros.
1071 Dumping is by default done on level `LOG_DEBUG`, this can be overridden by
1072 defining `NOBUG_DUMP_LEVEL` to some other level.
1074 // doc/dumpexample.txt:1 //
1075 .How to use the DUMP facilities
1078 -------------------------------------------------------
1082 char * STRING_MEMBER;
1083 struct STRUCTNAME* next;
1085 -------------------------------------------------------
1087 then you define a function like:
1090 -------------------------------------------------------
1092 nobug_STRUCTNAME_dump (const struct STRUCTNAME* self,
1098 // check for self != NULL and that the depth
1099 // limit did not exceed in recursive datastructures
1102 // use DUMP_LOG not LOG to print the data
1103 DUMP_LOG("STRUCTNAME %p: int is %d, string is %s", self,
1104 self->INTEGER_MEMBER,
1105 self->STRING_MEMBER);
1106 // now recurse with decremented depth
1107 nobug_STRUCTNAME_dump (self->next, depth-1, file, line, func);
1110 -------------------------------------------------------
1112 now you can use the DUMP() macros within the code
1115 -------------------------------------------------------
1118 struct STRUCTNAME foo;
1120 DUMP (my_flag, STRUCTNAME, &foo, 2);
1122 -------------------------------------------------------
1124 // src/nobug.h:652 //
1128 One can tag features as:
1134 Something which shouldn't be used in future
1140 not yet finished feature
1146 known bug to be fixed later
1152 enhancement to be done soon
1164 used to tag code-path which shall be never executed.
1168 ELSE_NOTREACHED(...)
1170 same as `else NOTREACHED()`, but wholly optimized out in release builds.
1172 // doc/annotationtable.txt:1 //
1174 The advantage of this tagging over plain source comments is that we can take
1175 some actions if we run in such a tag at compile or runtime:
1177 the action to be taken when such a macro is hit depends on the build level:
1180 `-------------`-----`------------`-----------------------------------------
1182 ---------------------------------------------------------------------------
1183 DEPRECATED log nothing wont compile
1184 UNIMPLEMENTED abort abort wont compile
1185 FIXME log wont compile wont compile
1186 TODO log log wont compile
1187 PLANNED log nothing nothing
1188 NOTREACHED abort abort removed
1189 ---------------------------------------------------------------------------
1193 * abort means first log and then abort
1194 * log will only log once for each sourceline (not on each hit)
1195 * wont compile will abort compilation with a error message
1196 * nothing optimized out, sane way
1197 * removed optimized out for performance reasons
1199 // doc/scopechecks.txt:1 //
1205 The programmer can tag any scope as `UNCHECKED` or `CHECKED`. In *ALPHA* and *BETA*
1206 builds, a global `UNCHECKED` is implied. In *RELEASE* builds, `UNCHECKED` scopes are
1209 // doc/assertiontable.txt:1 //
1210 .Assertions active depending on Build level and Scope
1212 `-----------`-----------------------------------------`-----------------------------`-------------------
1213 *ALPHA* *BETA* *RELEASE*
1214 *UNCHECKED* Preconditions, Postconditions, Invariants Preconditions, Postconditions compiling will abort
1215 *CHECKED* Preconditions, Postconditions Preconditions
1216 ------------------------------------------------------------------------------------------------------
1218 // src/nobug.h:779 //
1222 NoBug has some macros which can be used to simulate errorneous behaviour:
1226 INJECT_GOODBAD(expr, good, bad)
1228 substitutes to an expression and returns good when expr is false and
1229 bad when expr is true. In BETA and RELEASE builds 'good' is always returned.
1233 INJECT_FAULT(expr, bad)
1235 substitutes to a statement which executes 'bad'
1236 when expr is true. Optimitzed out in BETA and RELEASE builds.
1240 In both cases, when a fault is injected it will be logged at
1241 `NOBUG_INJECT_LEVEL` (default: `LOG_NOTICE`). This can be defined
1242 before including 'nobug.h' to override it.
1244 // doc/resourcetracking.txt:1 //
1248 With little effort, NoBug can watch all kinds of resources a program uses. This
1249 becomes useful for resources which are distributed over a multithreaded
1250 program. Resource tracking is only active in ALPHA builds and optimized out in
1251 BETA and RELEASE builds.
1256 Resources are abstracted, NoBug has little knowledge about the semantics of a
1257 resource, it only keeps records of resources and the code using it and ensures
1258 basic constraints. Detailed usage checks of resource have to be done with other
1261 Resources are identified by a arbitrary identifier which is just a
1262 pointer. Additionally a name, the type and the source locations which
1263 announced the resource are stored.
1265 Code which wants to use a resource calls a enter macro with its own identifier
1266 and state, then might alter the state and finally a leave macro when finished
1269 When a resource is used one has to pass one of this states:
1271 * NOBUG_RESOURCE_WAITING
1272 + For resources where acquisition could block (locks) you enter it with a
1273 WAITING state first and as soon you acquired it you change the state to one
1275 * NOBUG_RESOURCE_EXCLUSIVE
1276 + Acquired the resource exclusively. It must not be acquired
1277 again, not even from the same thread.
1278 * NOBUG_RESOURCE_RECURSIVE
1279 + The resource might be entered multiple times from the same
1280 thread with this state.
1281 * NOBUG_RESOURCE_SHARED
1282 + The resource might be entered multiple times from any thread
1285 Possible state transitions:
1287 ["graphviz", "resource-transistinons.png"]
1288 ---------------------------------------------------------------------
1291 edge [fontname=Courier fontsize=10]
1293 start [shape=ellipse]
1297 start -> Waiting [label="ENTER()"]
1298 start -> Exclusive [label="ENTER()"]
1299 start -> Recursive [label="ENTER()"]
1301 Waiting -> Exclusive [label="STATE()"]
1302 Waiting -> Recursive [label="STATE()"]
1304 Recursive -> Recursive [label="ENTER()\nSTATE()"]
1306 Waiting -> end [label="LEAVE()"]
1307 Exclusive -> end [label="LEAVE()"]
1308 Recursive -> end [label="LEAVE()"]
1312 ---------------------------------------------------------------------
1317 There are small race conditions in the time we
1318 announce/forget/enter/remove resources and doing the actual call to a
1319 resource. These race conditions affect the reporting exactness and are
1320 a design decision. When this poses a problem it will be fixed.
1322 The Resource Tracker relies on proper announce/forget and enter/leave
1323 are properly pairing. The programmer should ensure that this is done
1324 right, otherwise the results are unpredictable.
1326 // src/nobug.h:996 //
1327 Resource tracking macros
1328 ~~~~~~~~~~~~~~~~~~~~~~~~
1330 [[RESOURCE_LOGGING]]
1331 [[RESOURCE_LOG_LEVEL]]
1333 Unless the user defines `NOBUG_RESOURCE_LOGGING` to 0 each of the above macros
1334 will emit a log message at `NOBUG_RESOURCE_LOG_LEVEL` which defaults to
1339 RESOURCE_HANDLE(name)
1340 RESOURCE_HANDLE_INIT(name)
1342 RESOURCE_USER_INIT(name)
1344 Define and initialize handles for to track resources.
1347 identifer to be used for the handle
1349 There are two kinds of handles, each resource itself is abstracted with a
1350 `RESOURCE_HANDLE` and every access to this resources is tracked through a
1351 `RESOURCE_USER` handle. These macros takes care that the declaration is optimized
1352 out in the same manner as the rest of the resource tracker would be disabled.
1353 You can still instantiate handles as `struct nobug_resource_record*` or
1354 `struct nobug_resource_user*` in structures which must have a constant size
1355 unconditional of the build level. The two `*_INIT` macros can be used to initialize
1356 resource handles and are optimized out when the resource tracker gets disabled.
1358 [[RESOURCE_ANNOUNCE]]
1360 RESOURCE_ANNOUNCE(flag, type, name, identifier, handle)
1362 Publishes resources.
1365 the NoBug flag which turns logging on for this macro
1367 a string which should denote the domain of the resource,
1368 examples are "file", "mutex", "lock", "database" and so on
1370 the actual name of a named resource this as string which
1371 together with type forms a unique identifier of the resource. `type` and
1372 `name` must be available through the entire lifetime of the resource, using
1373 literal strings is recommended
1375 a pointer which should be unique for this resource, any
1376 kind of pointer will suffice, it is only used for identification. In
1377 multithreaded applications the thread identifier becomes an additional
1380 a `NOBUG_RESOURCE_HANDLE` which will be initialized to point to
1381 the newly created resource.
1383 Resources must be unique, it is a fatal error when a resource it tried to be
1384 announced more than one time.
1388 RESOURCE_FORGET(flag, handle)
1390 Removes resources that have become unavailable from the registry.
1393 the NoBug flag which turns logging on for this macro
1395 the `NOBUG_RESOURCE_HANDLE` used to track this resource
1397 The resource must still exist and no users must be attached to it, else a fatal
1402 RESOURCE_ENTER(flag, announced, user, state, handle)
1407 nobug flag which turns logging on for this macro
1409 the handle set by `RESOURCE_ANNOUNCE`
1411 a free-form identifier
1413 the initial state, one of `NOBUG_RESOURCE_WAITING`,
1414 `NOBUG_RESOURCE_EXCLUSIVE`, `NOBUG_RESOURCE_RECURSIVE` or `NOBUG_RESOURCE_SHARED`
1416 a `NOBUG_RESOURCE_HANDLE` which will be initialized to the
1422 RESOURCE_WAIT(flag, resource, user, handle)
1424 This is just an alias for RESOURCE_ENTER(flag, resource, user, NOBUG_RESOURCE_WAITING, handle)
1429 RESOURCE_WAIT(flag, resource, user, handle);
1430 if (lock_my_resource() == ERROR)
1431 NOBUG_RESOURCE_LEAVE(flag, handle);
1433 RESOURCE_STATE(flag, NOBUG_RESOURCE_EXCLUSIVE, handle);
1438 RESOURCE_TRY(flag, resource, user, handle)
1440 This is just an alias for RESOURCE_ENTER(flag, resource, user, NOBUG_RESOURCE_TRYING, handle).
1441 Trying on a resource is similar to waiting but will not trigger a deadlock check. This can be used
1442 when a deadlock is expected at runtime and one handles this otherwise (by a timed wait or something like that).
1446 RESOURCE_STATE(flag, entered, state)
1448 Changes resource's state.
1451 is nobug flag which turns logging on for this macro
1453 the new state Note that only certain state transitions are
1454 allowed, see discussion/diagram above
1456 the handle set by `RESOURCE_ENTER`
1460 RESOURCE_LEAVE(flag, handle)
1462 Disconnect from a resource identified with its handle.
1465 nobug flag which turns logging on for this macro
1467 the handle you got while entering the resource
1469 'RESOURCE_LEAVE()' acts like the head of a C loop statement, it ties to the following
1470 (block-) statement. Leaving and the user defined following statement are atomic.
1471 This statement must not be left by break, return or any other kind of jump. NoBug does
1472 not assert this (for for Performance reasons).
1477 NOBUG_RESOURCE_LEAVE(flag, handle)
1479 unlock_my_resource();
1483 [[RESOURCE_ASSERT_STATE]]
1484 .RESOURCE_ASSERT_STATE
1485 RESOURCE_ASSERT_STATE(resource, state)
1486 RESOURCE_ASSERT_STATE_IF(when, resource, state)
1488 Assert that we have a resource in a given state. For multithreaded programms the topmost
1489 state of the calling thread is checked, for non threadeded programs the most recent state on
1493 Condition which must be true for testing the assertion
1501 NOBUG_RESOURCE_DUMP(flag, handle)
1502 NOBUG_RESOURCE_DUMP_IF(when, flag, handle)
1504 Dump the state of a single resource.
1507 Condition which must be true to dump the resource
1509 Nobug flag for the log channel
1511 handle of the resource to be dumped
1513 [[RESOURCE_DUMPALL]]
1515 NOBUG_RESOURCE_DUMPALL(flag)
1516 NOBUG_RESOURCE_DUMPALL_IF(when, flag)
1518 Dump the state of all resources.
1521 Condition which must be true to dump the resources
1523 Nobug flag for the log channel
1527 NOBUG_RESOURCE_LIST(flag)
1528 NOBUG_RESOURCE_LIST_IF(when, flag)
1530 List all registered resources.
1533 Condition which must be true to list the resources
1535 Nobug flag for the log channel
1537 // doc/resourceexample.txt:1 //
1538 .How to use the Resourcetracker
1541 NOBUG_DEFINE_FLAG_LIMIT(test, LOG_DEBUG);
1545 // define a mutex and announce it
1546 pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
1547 RESOURCE_HANDLE(resource);
1549 // 'example' is just a pointer to this function which suffices as unique id
1550 RESOURCE_ANNOUNCE(test, "mutex", "my_mutex", example, resource);
1552 // the following would be done in a different thread in a real program
1554 RESOURCE_HANDLE(enter);
1556 // announce that we want to use the resource
1557 // &enter also suffices as unique pointer, which is all we need as identifer here
1558 RESOURCE_WAIT(flag, resource, &enter, enter)
1560 // lock() might block
1561 pthread_mutex_lock (&my_mutex);
1562 // assume no errors, got it, change the state
1563 RESOURCE_STATE(test, NOBUG_RESOURCE_EXCLUSIVE, enter);
1566 ////////////////////////////////////////
1567 // program does something useful here //
1568 ////////////////////////////////////////
1570 // we don't need it anymore
1571 RESOURCE_LEAVE(test, enter) // << no semicolon
1572 pthread_mutex_unlock (&my_mutex);
1574 // back in the main thread
1575 RESOURCE_FORGET(test, resource); // remove the resource from the public registry
1579 // doc/resourcedeadlock.txt:1 //
1583 The Resource Tracker is able to detect potential deadlocks. This is done by
1584 learning the relations between locks (precedence). A possible deadlock results
1585 in a log message and a fatal abort. Note that only waiting on resources can
1586 lead to a deadlock. Deadlock detection is implemented in the Resource Tracker
1587 and active in ALPHA builds and optimized out on any other build level.
1589 For details about the deadlock detection algorithm see
1590 xref:deadlock_detection[Appendix: Resource Tracking Alorithm].
1592 // src/nobug.h:2359 //
1596 NoBug provides callbacks, applications can use these
1597 to present logging information in some custom way or hook some special processing in.
1598 The callbacks are initialized to NULL and never modified by NoBug, its the solve responsibility
1599 of the user to manage them.
1601 CAUTION: There are certain constraints what and what not can be done in callbacks
1602 documented below which must be followed.
1605 .type of logging callbacks
1606 typedef void (*nobug_logging_cb)(const struct nobug_flag* flag, int priority, const char *log, void* data)
1608 used for the logging callbacks
1611 Flag structure which defines the logging configuration for this event
1613 Log level of the current event
1615 Pointing to the current log line in the ringbuffer or `NULL`
1617 Global pointer defined by the user, passed arround (see below)
1620 .type of abort callback
1621 typedef void (*nobug_abort_cb)(void* data)
1623 used for the abort callback
1626 Global data defined by the user, passed arround (see below)
1629 .passing data to callbacks
1630 void* nobug_callback_data
1632 This global variable is initialized to `NULL` and will never be touched by NoBug. One can use it
1633 to pass extra data to the callback functions.
1635 [[logging_callback]]
1636 .callback when logging
1637 nobug_logging_cb nobug_logging_callback
1639 This callback gets called when something gets logged.
1640 NoBug will still hold its mutexes when calling this hook, calling NoBug logging or resource tracking
1641 functions from here recursively will deadlock and must be avoided.
1642 The `log` parameter points to the logging message in the ringbuffer.
1643 Unlike other logging targets it is not automatically limited to the log level configured
1644 in the flag but called unconditionally. The callback should implement its own limiting.
1646 When one wants to do complex calls which may include recursion into logging and resource tracking
1647 functions, the intended way is to pass contextual information possibly including a __copy__ of the
1648 `log` parameter in xref:THREAD_DATA[NOBUG_THREAD_DATA] to the postlogging callback (see below).
1649 Other internal NoBug facilties, like the ringbuffer etc, are protected by the mutexes and may be accessed
1652 [[postlogging_callback]]
1653 .callback after logging
1654 nobug_logging_cb nobug_postlogging_callback
1656 This callback gets called after something got logged. The `log` parameter is always NULL and all
1657 NoBug mutexes are released. This means that this function may call any complex things, including
1658 calling logging and resource tracking, but may not call internal NoBug facilities.
1659 Contextual created in the `nobug_logging_callback` and stored in xref:THREAD_DATA[NOBUG_THREAD_DATA] can be
1660 retrieved here and may need to be cleaned up here.
1663 .callback for aborting
1664 nobug_abort_cb nobug_abort_callback
1666 This callback gets called when the application shall be terminated due an error.
1667 It can be used to hook exceptions or similar things in. When it returns, `abort()`
1670 IMPORTANT: Errors detected by NoBug are always fatal. If one handles and possible
1671 throws an exception here, the application must shut down as soon as possible.
1672 Most causes for aborts are optimitzed out in `RELEASE` builds.
1674 // src/nobug.h:1519 //
1682 Using this macro one can pass a direct pointer to a flag where a name would
1683 be expected. This is sometimes convinient when flag pointers are passed around
1684 in management strutures and one wants to tie logging to dynamic targets.
1688 NOBUG_DEFINE_FLAG(myflag);
1690 struct nobug_flag* ptr = &NOBUG_FLAG(myflag);
1691 TRACE(NOBUG_FLAG_RAW(ptr), "Passed flag by pointer")
1698 The backtrace macro logs a stacktrace using the NoBug facilities.
1699 This is automatically called when NoBug finds an error and is due
1700 to abort. But one might call it manually too.
1706 This is the default implementation for aborting the program, it first syncs all ringbuffers to disk, then
1707 calls the abort callback if defined and then `abort()`.
1711 If not overridden, evaluates to `NOBUG_ABORT_`. One can override this before including
1712 `nobug.h` to customize abortion behaviour. This will be local to the translation unit then.
1714 [[NOBUG_ALPHA_COMMA]]
1716 NOBUG_ALPHA_COMMA(something)
1717 NOBUG_ALPHA_COMMA_NULL
1719 Sometimes it is useful to have initializer code only in *ALPHA* builds, for example when you
1720 conditionally include resource handles only in *ALPHA* versions. An initializer can then
1721 use this macros to append a comman and something else only in *ALPHA* builds as in:
1722 struct foo = {"foo", "bar" NOBUG_ALPHA_COMMA_NULL };
1727 NOBUG_IF_NOT_ALPHA(...)
1729 NOBUG_IF_NOT_BETA(...)
1730 NOBUG_IF_RELEASE(...)
1731 NOBUG_IF_NOT_RELEASE(...)
1733 This macros allow one to conditionally include the code in '(...)' only if the
1734 criteria on the build level is met. If not, nothing gets substituted. Mostly used
1735 internally, but can also be used for custom things.
1737 // doc/multithreading.txt:1 //
1742 It is important that NoBug protects certain operations with locks in
1743 multithreaded programs. You have to ensure that 'HAVE_PTHREAD_H' is defined by
1744 the configuration system and use the 'libnobugmt' library for linking. It is
1745 particular important that libraries using NoBug are compiled with
1746 'HAVE_PTHREAD_H' enabled when they are intended to be used in multithreaded
1749 When Multithreading is used, log messages contain a identifier of the
1750 originating thread. This identifier should be set by
1753 .NOBUG_THREAD_ID_SET
1754 NOBUG_THREAD_ID_SET(name)
1757 New name for the thread
1759 Nobug will assemble a unique identifier by appending a underscore and a
1760 number to name, for example `NOBUG_THREAD_ID_SET("gui")` will result in a
1761 identifier like "gui_5". When you don't set a thread identifier, then NoBug
1762 assigns one automatically with the name 'thread' preprended if needed. Thread
1763 identifiers may be reset with a new call to this macro.
1766 .NOBUG_THREAD_ID_GET
1769 Will return a const char* of the thread id in multithreaded programs and
1770 a pointer to a literal empty string in singlethreaded programs.
1776 Evaluates to a variable of type `void*` which can be used to store
1777 thread local information. This is useable for xref:_callbacks[callbacks] which may
1778 prepare context information to be reused later.
1780 This macro is also available in singlethreaded programs, refering to a
1781 single global variable.
1783 Nobug initializes this variable to `NULL` and then touches it never again.
1786 // src/nobug_rbdump.c:31 //
1788 Dumping Persistent Ringbuffers
1789 ------------------------------
1791 NoBug installs the `nobug_rbdump` tool for dumping the content of a persistent
1792 ringbuffer. It is invoked with the filename of the ringbuffer, the content is then
1795 // doc/testsuite.txt:1 //
1799 TODO Documentation to be written, use the source Luke!
1801 NoBug maintains a `test.sh` script which drives extensive testsuites.
1802 Look at into the 'tests/' folder about how to apply this.
1804 // doc/bestpractices.txt:1 //
1808 NOTE: this section is very work in progress
1813 * Write a testsuite, build your program with -O0 -g -DEBUG_ALPHA and run
1814 the testsuite under valgrind control. Hack until the program mets the
1815 specifications defined by the testsuite.
1817 * Build with desired optimization level and -g -DEBUG_BETA and give the
1818 program to your beta testers.
1820 * Build it with optimization and without -g -DEBUG_*
1822 .What and when to check
1824 * Add REQUIRE checks on your interfaces (incoming parameters). Especially if
1825 a argument might not cover the whole range of the underlying type.
1826 * Don't waste your and your CPU's time with unnecessary checks. The testsuite
1827 should validate your program. NoBug aids in debugging. You can add
1828 Postconditions (ENSURE) and Invariants when you have a bug somewhere and
1829 want to nail it down.
1830 * Added checks don't need to be removed.
1831 * When you use the CHECKED/UNCHECKED features then don't forget C scoping
1832 rules, tag things as CHECKED from the leaves to the root.
1836 * TRACE(flagname) or TRACE_DBG(flagname) at the begin of every nontrivial
1837 function will easily log the progress of your application.
1838 * Trying a RELEASE build will abort on certain conditions (known BUG, TODO's,
1839 UNCHECKED code), you can use this to find these spots.
1844 // src/nobug_resources.c:298 //
1845 [[deadlock_detection]]
1846 The Resource Tracking Algorithm
1847 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1849 Each resource registers a global 'resource_record'.
1851 Every new locking path discovered is stored as 'resource_node' structures which refer to the associated
1854 Threads keep a trail of 'resource_user' strcutures for each resource entered. This 'resource_user' struct
1855 refer to the 'resource_nodes' and thus indirectly to the associated 'resource_record'.
1857 The deadlock checker uses this information to test if the acqusition of a new resource would yield a
1860 [[nobug_resource_enter]]
1864 In multithreaded programs, whenever a thread wants to wait for a 'resource_record'
1865 the deadlock checker jumps in.
1867 The deadlock checking algorithm is anticipatory as it will find and abort on conditions which may lead
1868 to a potential deadlock by violating the locking order learned earlier.
1870 Each thread holds a stack (list) of each 'resource_user' it created. Leaving
1871 a resource will remove it from this stacklist.
1873 Each 'resource_record' stores the trail which other 'resource_records' are already entered. This relations
1874 are implemented with the 'resource_node' helper structure.
1877 TODO: insert diagram here
1890 First we find out if there is already a node from the to be acquired resource back to
1891 the topmost node of the current threads user stack.
1894 ---------------------------------------------------------------------
1895 struct nobug_resource_user* user = NULL;
1896 struct nobug_resource_node* node = NULL;
1898 if (!llist_is_empty (&tls->res_stack))
1900 user = LLIST_TO_STRUCTP (llist_tail (&tls->res_stack),
1901 struct nobug_resource_user,
1904 struct nobug_resource_node templ =
1907 user->current->resource,
1911 node = (struct nobug_resource_node*)
1912 llist_ufind (&resource->nodes,
1914 nobug_resource_node_resource_cmpfn,
1918 ---------------------------------------------------------------------
1920 Deadlock checking is only done when the node is entered in `WAITING` state and only
1921 available in multithreaded programs.
1924 ---------------------------------------------------------------------
1925 if (state == NOBUG_RESOURCE_WAITING)
1927 #if NOBUG_USE_PTHREAD
1929 ---------------------------------------------------------------------
1931 If node was found above, then this locking path is already validated and no deadlock can happen,
1932 else, if this stack already holds a resource (user is set) we have to go on with checking.
1935 ---------------------------------------------------------------------
1939 ---------------------------------------------------------------------
1941 If not then its checked that the resource to be entered is not on any parent trail of the current topmost resource,
1942 if it is then this could be a deadlock which needs to be further investigated.
1945 ---------------------------------------------------------------------
1946 LLIST_FOREACH (&user->current->resource->nodes, n)
1948 for (struct nobug_resource_node* itr =
1949 ((struct nobug_resource_node*)n)->parent;
1953 if (itr->resource == resource)
1956 ---------------------------------------------------------------------
1958 if the resource was on the trail, we search if there is a common ancestor before the resource
1959 on the trail and the threads current chain,
1960 if yes then this ancestor protects against deadlocks and we can continue.
1963 ---------------------------------------------------------------------
1964 for (struct nobug_resource_node* itr2 = itr->parent;
1966 itr2 = itr2->parent)
1968 LLIST_FOREACH_REV (&tls->res_stack, p)
1970 struct nobug_resource_user* user =
1971 LLIST_TO_STRUCTP (p,
1972 struct nobug_resource_user,
1974 if (user->current->resource == itr2->resource)
1977 ---------------------------------------------------------------------
1979 If no ancestor found, we finally abort with a potential deadlock condition.
1982 ---------------------------------------------------------------------
1983 nobug_resource_error = "possible deadlock detected";
1986 ---------------------------------------------------------------------
1989 [[nobug_resource_leave]]
1993 store the tail and next aside, we need it later
1996 ---------------------------------------------------------------------
1997 #if NOBUG_USE_PTHREAD
1998 struct nobug_resource_user* tail =
1999 LLIST_TO_STRUCTP (llist_tail (&user->thread->res_stack),
2000 struct nobug_resource_user,
2002 struct nobug_resource_user* next =
2003 LLIST_TO_STRUCTP (llist_next (&user->res_stack),
2004 struct nobug_resource_user,
2006 ---------------------------------------------------------------------
2008 remove user struct from thread stack
2009 The res_stack is now like it is supposed to look like with the 'user' removed.
2010 We now need to fix the node tree up to match this list.
2013 ---------------------------------------------------------------------
2014 llist_unlink_fast_ (&user->res_stack);
2015 ---------------------------------------------------------------------
2017 When the the user node was not the tail or only node of the thread stack, we have to check
2018 (and possibly construct) a new node chain for it. No valdation of this chain needs to be done,
2019 since it was already validated when entering the resources first.
2022 ---------------------------------------------------------------------
2023 if (user != tail && !llist_is_empty (&user->thread->res_stack))
2025 struct nobug_resource_user* parent = NULL;
2026 if (llist_head (&user->thread->res_stack) != &next->res_stack)
2029 LLIST_TO_STRUCTP (llist_prev (&next->res_stack),
2030 struct nobug_resource_user,
2033 ---------------------------------------------------------------------
2035 iterate over all users following the removed node, finding nodes pointing to this users or
2039 ---------------------------------------------------------------------
2040 LLIST_FORRANGE (&next->res_stack, &user->thread->res_stack, n)
2042 struct nobug_resource_user* cur =
2043 LLIST_TO_STRUCTP (n,
2044 struct nobug_resource_user,
2047 ---------------------------------------------------------------------
2048 // src/nobug_resources.c:647 //
2050 find the node pointing back to parent, create a new one if not found, rinse repeat
2053 ---------------------------------------------------------------------
2054 struct nobug_resource_node templ =
2061 struct nobug_resource_node* node = (struct nobug_resource_node*)
2062 llist_ufind (&resource->nodes,
2064 nobug_resource_node_parent_cmpfn,
2069 node = nobug_resource_node_new (resource,
2070 parent?parent->current:NULL);
2073 nobug_resource_error = "internal allocation error";
2081 ---------------------------------------------------------------------
2087 xref:ABORT[Aborting]:: abort the program
2088 xref:abort_callback[callback for aborting]:: hook to handle a termination
2089 xref:abort_cb[type of abort callback]:: type of a abort callback function
2090 xref:ALERT[ALERT]:: about to die
2091 xref:ASSERT[ASSERT]:: generic assertion
2092 xref:assert[assert]:: C standard assertion
2093 xref:BACKTRACE[Backtraces]:: generate a backtrace
2094 xref:buildlevel[Build Levels]:: selecting the build level
2095 xref:callback_data[passing data to callbacks]:: data to be passed to callbacks
2096 xref:CHECK[CHECK]:: unnconditional assertion for testsuites
2097 xref:CHECKED[CHECKED, Scope]:: tag scope as reviewed
2098 xref:Cplusplus_logflags[C++ support, C++ logflags]:: C++ support for log flags
2099 xref:CRITICAL[CRITICAL]:: can not continue
2100 xref:deadlock_detection[The Resource Tracking Algorithm]:: how resources are tracked
2101 xref:DECLARE_FLAG[DECLARE_FLAG]:: declaring a flag
2102 xref:DECLARE_ONLY[DECLARE_ONLY]:: force flag declarations only
2103 xref:DEFINE_FLAG[DEFINE_FLAG]:: defining a flag
2104 xref:DEFINE_FLAG_LIMIT[DEFINE_FLAG_LIMIT]:: defining a flag w/ log limit
2105 xref:DEFINE_FLAG_PARENT[DEFINE_FLAG_PARENT]:: defining a flag hierarchy
2106 xref:DEFINE_FLAG_PARENT_LIMIT[DEFINE_FLAG_PARENT_LIMIT]:: defining a flag hierarchy, w/ log limit
2107 xref:DEPRECATED[DEPRECATED]:: to be discarded in future
2108 xref:DUMP[DUMP]:: dumping datastructures
2109 xref:DUMP_LOG[DUMP_LOG]:: logging helper for dumping
2110 xref:ECHO[ECHO]:: unconditional logging for tests
2111 xref:ELSE_NOTREACHED[ELSE_NOTREACHED]:: alternative never taken
2112 xref:ENSURE[ENSURE]:: postconditions (computation outcomes)
2113 xref:ERROR[ERROR]:: something gone wrong
2114 xref:FIXME[FIXME]:: known bug
2115 xref:INFO[INFO]:: progress message
2116 xref:INJECT_FAULT[INJECT_FAULT]:: fault injection statement
2117 xref:INJECT_GOODBAD[INJECT_GOODBAD]:: fault injection expression
2118 xref:INJECT_LEVEL[INJECT_LEVEL]:: log level for fault injection
2119 xref:INVARIANT[INVARIANT]:: validate invariant state
2120 xref:LOG[LOG]:: generic logging
2121 xref:LOG_BASELIMIT[LOG_BASELIMIT]:: minimum compliled-in logging limit
2122 xref:logflags[Log Flags]:: define hierarchies for logging output
2123 xref:logging_callback[callback when logging]:: hook when something get logged
2124 xref:logging_cb[type of logging callbacks]:: type of a logging callback function
2125 xref:multithreading[Multithreading]:: using NoBug in multithreaded programs
2126 xref:NOBUG_ALPHA_COMMA[NOBUG_ALPHA_COMMA]:: append something after a comma in *ALPHA* builds
2127 xref:NOBUG_ANN[NOBUG_ANN]:: log flag for annotations
2128 xref:NOBUG_ENV[Control what gets logged]:: environment variable for loging control
2129 xref:nobug_flag[nobug (flag)]:: log flag used to show nobug actions
2130 xref:NOBUG_FLAG_RAW[NOBUG_FLAG_RAW]:: pass direct flag pointer
2131 xref:NOBUG_IF[NOBUG_IF_*]:: include code conditionally on build level
2132 xref:NOBUG_ON[NOBUG_ON]:: log flag which is always enabled
2133 xref:nobug_resource_enter[Entering Resources]:: deadlock check on enter
2134 xref:nobug_resource_leave[Leaving Resources]:: fix resource lists
2135 xref:NOTICE[NOTICE]:: detailed progress message
2136 xref:NOTREACHED[NOTREACHED]:: code path never taken
2137 xref:PLANNED[PLANNED]:: ideas for future
2138 xref:postlogging_callback[callback after logging]:: hook after something get logged
2139 xref:rbdump[Dumping Persistent Ringbuffers]:: dumping persistent ringbuffers
2140 xref:REQUIRE[REQUIRE]:: preconditions (input parameters)
2141 xref:RESOURCE_ANNOUNCE[RESOURCE_ANNOUNCE]:: publish new resources
2142 xref:RESOURCE_ASSERT_STATE[RESOURCE_ASSERT_STATE]:: assert the state of a resource
2143 xref:RESOURCE_DUMP[RESOURCE_DUMP]:: dump the state of a single resource
2144 xref:RESOURCE_DUMPALL[RESOURCE_DUMPALL]:: dump the state of all resources
2145 xref:RESOURCE_ENTER[RESOURCE_ENTER]:: claim a resource
2146 xref:RESOURCE_FORGET[RESOURCE_FORGET]:: remove resources
2147 xref:RESOURCE_HANDLE[RESOURCE_HANDLE]:: define resource handles
2148 xref:RESOURCE_LEAVE[RESOURCE_LEAVE]:: relinquish a claimed resource
2149 xref:RESOURCE_LIST[RESOURCE_LIST]:: enumerate all registered resources
2150 xref:RESOURCE_LOG_LEVEL[RESOURCE_LOG_LEVEL]:: select the log level for resource logging
2151 xref:RESOURCE_LOGGING[RESOURCE_LOGGING]:: switch resource logging on and off
2152 xref:RESOURCE_STATE[RESOURCE_STATE]:: change the state of a resource
2153 xref:RESOURCE_TRY[RESOURCE_TRY]:: wait for a resource to become available
2154 xref:RESOURCE_WAIT[RESOURCE_WAIT]:: wait for a resource to become available
2155 xref:THREAD_DATA[NOBUG_THREAD_DATA]:: thread local data for application use
2156 xref:THREAD_ID_GET[NOBUG_THREAD_ID_GET]:: query thread id
2157 xref:THREAD_ID_SET[NOBUG_THREAD_ID_SET]:: set or reset thread id
2158 xref:TODO[TODO]:: things to be done
2159 xref:TRACE[TRACE]:: debugging level message
2160 xref:UNCHECKED[UNCHECKED, Scope]:: tag scope as unreviewed
2161 xref:UNIMPLEMENTED[UNIMPLEMENTED]:: not yet implemented
2162 xref:WARN[WARN]:: unexpected fixable error
2164 // doc/license.txt:1 //
2169 Copyright (C) 2009 Christian Thäter <ct@pipapo.org>
2171 This program is free software; you can redistribute it and/or modify
2172 it under the terms of the GNU General Public License as published by
2173 the Free Software Foundation; either version 2 of the License, or
2174 (at your option) any later version.
2176 This program is distributed in the hope that it will be useful,
2177 but WITHOUT ANY WARRANTY; without even the implied warranty of
2178 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2179 GNU General Public License for more details.
2181 You should have received a copy of the GNU General Public License along
2182 with this program; if not, write to the Free Software Foundation, Inc.,
2183 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2187 NoBug is released under the "GNU General Public License version 2 or
2188 any later" to protect its freedom. If one wants to use NoBug in a
2189 propietary program, please contact the main author for
2190 acknowledging relicensing terms.
2192 For BSD license style Free Software, this means you can not distribute
2193 binaries linking NoBug without making its source available. To make
2194 this compatible, it is suggested that you dual-license your software
2195 with your prefered BSD like license and the GPL. As long as it uses
2196 NoBug, the GPL will take over and you have to make the source
2197 available, while one can ship a BSD or LGPL Licensed headerfile which
2198 defines all NoBug macros as empty macros and remove libnobug from the
2199 linking, then NoBug isn't used anymore and you may apply BSD license
2200 terms for resulting binaries.
2203 Contributor Agreement
2204 ~~~~~~~~~~~~~~~~~~~~~
2206 Improvements and patches must be licensed as "GPL v2 or any later" to
2207 be acceptable. Further a contributor must either assign his copyright
2208 to the main NoBug author or agree with the possibility that NoBug can
2209 be relicensed for propietary use:
2211 Independent of the GPL license as stated above, The main author of
2212 NoBug explicitly reserve the right to relicense NoBug under
2213 different, even propietary terms. Any contributor agrees to such
2214 a possiblility by sending his contribution to be included into
2215 the official releases.
2217 This agreement is bilateral, every contributor who worked on a
2218 substantial part of NoBug has the right to relicense it after
2219 negotiation with the NoBug main author. Exact terms of such
2220 relicensing are worked out on a per case base.
2222 The intention is that anyone who worked on NoBug should be able to
2223 benefit from his work. This means one should be able to use it at his
2224 workplace, to gain a job or as well as relicense it for a customer.
2225 Unlike other projects which simply ask for transfering the copyright
2226 to the main author, NoBug tries to make it possible to retain the
2227 copyright by anyone who helped the project.
2229 This additional agreement has no impact on the GPL, it's sole purpose
2230 is to define relicensing policies between the NoBug main author and
2231 contributors. When you recieve NoBug it will be licensed under
2232 GPL unless you personally acknowledged other terms with the NoBug main
2233 author (or any other main contributor).
2235 If anyone feels he is not credited in the 'AUTHORS' file or in any
2236 copyright notice, please contact the main author for inclusion.