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 supported
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__+++`, `+++__LINE__+++` and `+++__func__+++` macros to
814 log information on the current file, line number and function.
815 Moreover, all the flat namespace uppercase identifiers make it ease
816 to recognise the macros in source code.
818 All macros are available without condition with a `NOBUG_...` prefix.
819 Many macros (the common cases) are also available without this prefix
820 as a convenience, however macros without this prefix must not have
821 been previously defined. When `NOBUG_DISABLE_SHORTNAMES` is defined
822 before including 'nobug.h', then only the `NOBUG_` prefixed macros
823 are available and the short forms will never be defined.
825 A set of macros are provided by NoBug that are postfixed by `..._IF`.
826 These macros have the following form:
828 * `..._IF(when, ...)`
830 They perform the desired action only if `when` is true. For example:
832 * `REQUIRE_IF(foo != NULL, foo->something == constrained)`
834 The assertion will only be performed if `foo` is non `NULL`.
836 NoBug also also contains a facility to pass the source context (file,
837 line, function) around, this can be used to write functions which
838 handle things where one is more interested in the context of the caller
839 than the location where the macros appears.
841 This macros are postfixed with `..._CTX` and take an extra context
842 parameter (usually at last but before the logging format specifier and
843 any variable argument list). The context parameter must be of type
844 `const struct nobug_context`.
846 When the `_CTX` context form is used together with the conditional `_IF`
847 form then the suffix of the macros is always `..._IF_CTX`.
849 The macros which take a context have no short form and must always be
850 prefixed with `NOBUG_...`.
852 // doc/parametertable.txt:1 //
856 We use names for parameters which describe their type. These names are
857 orthogonal through all macro definitions.
860 `---------`------------------------------------------------------------------
861 `when` Assertion is only performed if expression `when` is true at runtime
862 `expr` Test without side effects
863 `flag` Flag to enable custom logging groups
864 `type` Data type to be checked as a single identifier name
865 `pointer` Pointer to type
867 `depth` Depth for invariants and dumps
868 `context` Source context of type `struct nobug_context`
869 `...` printf-like format string followed by its arguments
870 ---------------------------------------------------------------------------
872 // src/nobug.h:625 //
879 NoBug passes information about the source location of a given statement in
880 `const struct nobug_context` structures. These can be generated with
881 `NOBUG_CONTEXT` or `NOBUG_CONTEXT_NOFUNC`. The later one doesn't define a
882 function name and must be used when the function context is not available
883 like in static initialization etc..
885 // src/nobug.h:102 //
892 CHECK_IF(when, expr, ...)
894 This assertion is never optimized out. Its main purpose is for implementing
895 testsuites where one want to assert tests independent of the build level
900 REQUIRE_IF(when, expr, ...)
901 NOBUG_REQUIRE_CTX(expr, context,...)
902 NOBUG_REQUIRE_IF_CTX(when, expr, context, ...)
904 Precondition (input) check. Use these macros to validate input a
905 function receives. The checks are enabled in *ALPHA* and *BETA* builds and
906 optimized out in *RELEASE* builds.
911 ENSURE_IF(when, expr, ...)
912 NOBUG_ENSURE_CTX(expr, context, ...)
913 NOBUG_ENSURE_IF_CTX(when, expr, context, ...)
915 Postcondition (progress/output) check. Use these macros to validate the
916 data a function produces (example: return value). `ENSURE` is enabled
917 unconditionally in *ALPHA* builds and optimized out in *BETA* builds for
918 scopes which are tagged as `CHECKED`.
920 The `ENSURE_IF` variants are enabled in *ALPHA* and *BETA* builds.
922 In *RELEASE* builds this checks are
923 always optimized out, scopes tagged as `UNCHECKED` are not permitted.
928 ASSERT_IF(when, expr, ...)
929 NOBUG_ASSERT_CTX(expr, context, ...)
930 NOBUG_ASSERT_IF_CTX(when, expr, context, ...)
932 Generic check. Use these macros when you want to validate something
933 which doesn't fall into one of the above categories. A example is when
934 a library function can return a unexpected result (scanf with syntax
935 error in the formatstring, when a constant/literal formatstring is
936 expected). The checks are enabled in *ALPHA* and *BETA* builds and
937 optimized out in *RELEASE* builds.
943 NoBug overrides the standard `assert` macro, using `NOBUG_ASSERT`.
944 This is just a compatibility feature, its use is not suggested.
948 INVARIANT(type, pointer, depth)
949 INVARIANT_IF(when,type, pointer, depth)
950 INVARIANT_ASSERT(expr, ...)
952 Checking invariants. You can provide more complex checking functions
953 which test the validity of datastructures. Invariants are only enabled
954 in *ALPHA* builds for scopes which are not tagged as `CHECKED` and
955 otherwise optimized out.
957 TODO: describe how to create invariant checks
959 // src/nobug.h:359 //
963 Logging targets a flag (except for `ECHO`) and is done at a log-level relating to syslog levels.
965 NOTE: there is no logging macro for `LOG_EMERG`, this is only used by the assertions as fatal message
971 Never optimized out, logs at LOG_NOTICE level. Its main purpose is for implementing
972 testsuites where one want to print and log messages independent of the build level
977 ALERT_IF(when, flag, ...)
978 NOBUG_ALERT_CTX(flag, context, ...)
979 NOBUG_ALERT_IF_CTX(when, flag, context, ...)
981 This is the most critical condition an application might log. This might be used
982 if an error occurs which can not be handled except a safe shutdown for example.
987 CRITICAL_IF(when, flag, ...)
988 NOBUG_CRITICAL_CTX(flag, context, ...)
989 NOBUG_CRITICAL_IF_CTX(when, flag, context, ...)
991 An error which can not be handled occured but the application does not need to be
992 shutdowen, perhaps waiting for an operator to fix the cause.
997 ERROR_IF(when, flag, ...)
998 NOBUG_ERROR_CTX(flag, context, ...)
999 NOBUG_ERROR_IF_CTX(when, flag, context, ...)
1001 Application takes a error handling brach
1006 WARN_IF(when, flag, ...)
1007 NOBUG_WARN_CTX(flag, context, ...)
1008 NOBUG_WARN_IF_CTX(when, flag, context, ...)
1010 Rare, handled but unexpected branch
1015 INFO_IF(when, flag, ...)
1016 NOBUG_INFO_CTX(flag, context, ...)
1017 NOBUG_INFO_IF_CTX(when, flag, context, ...)
1019 Message about program progress
1024 NOTICE_IF(when, flag, ...)
1025 NOBUG_NOTICE_CTX(flag, context, ...)
1026 NOBUG_NOTICE_IF_CTX(when, flag, context, ...)
1028 More detailed progress message
1033 TRACE_IF(when, flag, ...)
1034 NOBUG_TRACE_CTX(flag, context, ...)
1035 NOBUG_TRACE_IF_CTX(when, flag, context, ...)
1037 Very fine grained messages
1039 NOTE: that `TRACE` corresponds to `LOG_DEBUG`, because using `DEBUG` could be ambiguous.
1043 NOBUG_LOG_CTX(flag, lvl, context, ...)
1044 NOBUG_LOG_IF_CTX(when, flag, lvl, context, ...)
1046 Generic logging macro which takes the level explicitly,
1047 avoid this, unless you implement your own logging facilities.
1051 NOBUG_LOG_BASELIMIT_ALPHA
1052 NOBUG_LOG_BASELIMIT_BETA
1053 NOBUG_LOG_BASELIMIT_RELEASE
1056 anything more detailed than this base limits will be optimized out.
1057 This is used to reduce the logging overhead for *RELEASE* builds.
1058 By default the limit is set to `LOG_DEBUG` for *ALPHA* and *BETA*
1059 builds, so all logging is retained and `LOG_NOTICE` in *RELEASE*
1060 builds to log the application progress only coarsely then.
1062 This macros can be defined before including 'nobug.h' to some other
1063 log level (as defined in 'syslog.h').
1065 // doc/dumping.txt:1 //
1067 Dumping Datastructures
1068 ----------------------
1070 TODO How to write DUMP handlers
1072 One can write functions for dumping complex datastructures using the NoBug
1073 facilities. This is done by writing a custom function for each
1074 datastructure to be dumped which may recursively call other dumping
1075 functions. There are macros for logging within such a dumper function
1076 and for initiating a dump of a given datastructure.
1078 // src/nobug.h:305 //
1081 DUMP(flag, type, pointer, depth)
1082 DUMP_IF(when, flag, type, pointer, depth)
1084 This macros call a datastructure dump of the object (`pointer`) in question.
1085 `DUMP` is only available in *ALPHA* and *BETA* builds, `DUMP_IF` is also
1086 enabled for the RELEASE builds.
1091 DUMP_LOG_IF(when, ...)
1093 Any output from `DUMP` handlers should be done by these macros.
1095 Dumping is by default done on level `LOG_DEBUG`, this can be overridden by
1096 defining `NOBUG_DUMP_LEVEL` to some other level.
1098 // doc/dumpexample.txt:1 //
1099 .How to use the DUMP facilities
1102 -------------------------------------------------------
1106 char * STRING_MEMBER;
1107 struct STRUCTNAME* next;
1109 -------------------------------------------------------
1111 then you define a function like:
1114 -------------------------------------------------------
1116 nobug_STRUCTNAME_dump (const struct STRUCTNAME* self,
1122 // check for self != NULL and that the depth
1123 // limit did not exceed in recursive datastructures
1126 // use DUMP_LOG not LOG to print the data
1127 DUMP_LOG("STRUCTNAME %p: int is %d, string is %s", self,
1128 self->INTEGER_MEMBER,
1129 self->STRING_MEMBER);
1130 // now recurse with decremented depth
1131 nobug_STRUCTNAME_dump (self->next, depth-1, file, line, func);
1134 -------------------------------------------------------
1136 now you can use the DUMP() macros within the code
1139 -------------------------------------------------------
1142 struct STRUCTNAME foo;
1144 DUMP (my_flag, STRUCTNAME, &foo, 2);
1146 -------------------------------------------------------
1148 // src/nobug.h:643 //
1152 One can tag features as:
1158 Something which shouldn't be used in future
1164 not yet finished feature
1170 known bug to be fixed later
1176 enhancement to be done soon
1188 used to tag code-path which shall be never executed.
1192 ELSE_NOTREACHED(...)
1194 same as `else NOTREACHED()`, but wholly optimized out in release builds.
1196 // doc/annotationtable.txt:1 //
1198 The advantage of this tagging over plain source comments is that we can take
1199 some actions if we run in such a tag at compile or runtime:
1201 the action to be taken when such a macro is hit depends on the build level:
1204 `-------------`-----`------------`-----------------------------------------
1206 ---------------------------------------------------------------------------
1207 DEPRECATED log nothing wont compile
1208 UNIMPLEMENTED abort abort wont compile
1209 FIXME log wont compile wont compile
1210 TODO log log wont compile
1211 PLANNED log nothing nothing
1212 NOTREACHED abort abort removed
1213 ---------------------------------------------------------------------------
1217 * abort means first log and then abort
1218 * log will only log once for each sourceline (not on each hit)
1219 * wont compile will abort compilation with a error message
1220 * nothing optimized out, sane way
1221 * removed optimized out for performance reasons
1223 // doc/scopechecks.txt:1 //
1229 The programmer can tag any scope as `UNCHECKED` or `CHECKED`. In *ALPHA* and *BETA*
1230 builds, a global `UNCHECKED` is implied. In *RELEASE* builds, `UNCHECKED` scopes are
1233 // doc/assertiontable.txt:1 //
1234 .Assertions active depending on Build level and Scope
1236 `-----------`-----------------------------------------`-----------------------------`-------------------
1237 *ALPHA* *BETA* *RELEASE*
1238 *UNCHECKED* Preconditions, Postconditions, Invariants Preconditions, Postconditions compiling will abort
1239 *CHECKED* Preconditions, Postconditions Preconditions
1240 ------------------------------------------------------------------------------------------------------
1242 // src/nobug.h:770 //
1246 NoBug has some macros which can be used to simulate errorneous behaviour:
1250 INJECT_GOODBAD(expr, good, bad)
1252 substitutes to an expression and returns good when expr is false and
1253 bad when expr is true. In BETA and RELEASE builds 'good' is always returned.
1257 INJECT_FAULT(expr, bad)
1259 substitutes to a statement which executes 'bad'
1260 when expr is true. Optimitzed out in BETA and RELEASE builds.
1264 In both cases, when a fault is injected it will be logged at
1265 `NOBUG_INJECT_LEVEL` (default: `LOG_NOTICE`). This can be defined
1266 before including 'nobug.h' to override it.
1268 // doc/resourcetracking.txt:1 //
1272 With little effort, NoBug can watch all kinds of resources a program uses. This
1273 becomes useful for resources which are distributed over a multithreaded
1274 program. Resource tracking is only active in ALPHA builds and optimized out in
1275 BETA and RELEASE builds.
1280 Resources are abstracted, NoBug has little knowledge about the semantics of a
1281 resource, it only keeps records of resources and the code using it and ensures
1282 basic constraints. Detailed usage checks of resource have to be done with other
1285 Resources are identified by a arbitrary identifier which is just a
1286 pointer. Additionally a name, the type and the source locations which
1287 announced the resource are stored.
1289 Code which wants to use a resource calls a enter macro with its own identifier
1290 and state, then might alter the state and finally a leave macro when finished
1293 When a resource is used one has to pass one of this states:
1295 * NOBUG_RESOURCE_WAITING
1296 + For resources where acquisition could block (locks) you enter it with a
1297 WAITING state first and as soon you acquired it you change the state to one
1299 * NOBUG_RESOURCE_EXCLUSIVE
1300 + Acquired the resource exclusively. It must not be acquired
1301 again, not even from the same thread.
1302 * NOBUG_RESOURCE_RECURSIVE
1303 + The resource might be entered multiple times from the same
1304 thread with this state.
1305 * NOBUG_RESOURCE_SHARED
1306 + The resource might be entered multiple times from any thread
1309 Possible state transitions:
1311 ["graphviz", "resource-transistinons.png"]
1312 ---------------------------------------------------------------------
1315 edge [fontname=Courier fontsize=10]
1317 start [shape=ellipse]
1321 start -> Waiting [label="ENTER()"]
1322 start -> Exclusive [label="ENTER()"]
1323 start -> Recursive [label="ENTER()"]
1325 Waiting -> Exclusive [label="STATE()"]
1326 Waiting -> Recursive [label="STATE()"]
1328 Recursive -> Recursive [label="ENTER()\nSTATE()"]
1330 Waiting -> end [label="LEAVE()"]
1331 Exclusive -> end [label="LEAVE()"]
1332 Recursive -> end [label="LEAVE()"]
1336 ---------------------------------------------------------------------
1341 There are small race conditions in the time we
1342 announce/forget/enter/remove resources and doing the actual call to a
1343 resource. These race conditions affect the reporting exactness and are
1344 a design decision. When this poses a problem it will be fixed.
1346 The Resource Tracker relies on proper announce/forget and enter/leave
1347 are properly pairing. The programmer should ensure that this is done
1348 right, otherwise the results are unpredictable.
1350 // src/nobug.h:987 //
1351 Resource tracking macros
1352 ~~~~~~~~~~~~~~~~~~~~~~~~
1354 [[RESOURCE_LOGGING]]
1355 [[RESOURCE_LOG_LEVEL]]
1357 Unless the user defines `NOBUG_RESOURCE_LOGGING` to 0 each of the above macros
1358 will emit a log message at `NOBUG_RESOURCE_LOG_LEVEL` which defaults to
1363 RESOURCE_HANDLE(name)
1364 RESOURCE_HANDLE_INIT(name)
1366 RESOURCE_USER_INIT(name)
1368 Define and initialize handles for to track resources.
1371 identifer to be used for the handle
1373 There are two kinds of handles, each resource itself is abstracted with a
1374 `RESOURCE_HANDLE` and every access to this resources is tracked through a
1375 `RESOURCE_USER` handle. These macros takes care that the declaration is optimized
1376 out in the same manner as the rest of the resource tracker would be disabled.
1377 You can still instantiate handles as `struct nobug_resource_record*` or
1378 `struct nobug_resource_user*` in structures which must have a constant size
1379 unconditional of the build level. The two `*_INIT` macros can be used to initialize
1380 resource handles and are optimized out when the resource tracker gets disabled.
1382 [[RESOURCE_ANNOUNCE]]
1384 RESOURCE_ANNOUNCE(flag, type, name, identifier, handle)
1385 NOBUG_RESOURCE_ANNOUNCE_RAW(flagptr, type, name, ptr, handle)
1386 NOBUG_RESOURCE_ANNOUNCE_RAW_CTX(flagptr, type, name, ptr, handle, context)
1388 Publishes resources.
1391 the NoBug flag name which turns logging on for this macro
1393 a string which should denote the domain of the resource,
1394 examples are "file", "mutex", "lock", "database" and so on
1396 the actual name of a named resource this as string which
1397 together with type forms a unique identifier of the resource. `type` and
1398 `name` must be available through the entire lifetime of the resource, using
1399 literal strings is recommended
1401 a pointer which should be unique for this resource, any
1402 kind of pointer will suffice, it is only used for identification. In
1403 multithreaded applications the thread identifier becomes an additional
1406 a `NOBUG_RESOURCE_HANDLE` which will be initialized to point to
1407 the newly created resource.
1409 Resources must be unique, it is a fatal error when a resource it tried to be
1410 announced more than one time.
1414 RESOURCE_FORGET(flag, handle)
1415 NOBUG_RESOURCE_FORGET_RAW(flagptr, handle)
1416 NOBUG_RESOURCE_FORGET_RAW_CTX(flagptr, handle, context)
1418 Removes resources that have become unavailable from the registry.
1421 the NoBug flag which turns logging on for this macro
1423 the `NOBUG_RESOURCE_HANDLE` used to track this resource
1425 The resource must still exist and no users must be attached to it, else a fatal
1430 RESOURCE_ENTER(flag, announced, user, state, handle)
1431 NOBUG_RESOURCE_ENTER_CTX(flag, resource, user, state, handle, context)
1436 nobug flag which turns logging on for this macro
1438 the handle set by `RESOURCE_ANNOUNCE`
1440 a free-form identifier
1442 the initial state, one of `NOBUG_RESOURCE_WAITING`, `NOBUG_RESOURCE_TRYING`,
1443 `NOBUG_RESOURCE_EXCLUSIVE`, `NOBUG_RESOURCE_RECURSIVE` or `NOBUG_RESOURCE_SHARED`
1445 a `NOBUG_RESOURCE_HANDLE` which will be initialized to the
1450 RESOURCE_WAIT(flag, resource, user, handle)
1451 NOBUG_RESOURCE_WAIT_CTX(flag, resource, user, handle, context)
1453 This is just an alias for RESOURCE_ENTER(flag, resource, user, NOBUG_RESOURCE_WAITING, handle)
1458 RESOURCE_WAIT(flag, resource, user, handle);
1459 if (lock_my_resource() == ERROR)
1460 NOBUG_RESOURCE_LEAVE(flag, handle);
1462 RESOURCE_STATE(flag, NOBUG_RESOURCE_EXCLUSIVE, handle);
1467 RESOURCE_TRY(flag, resource, user, handle)
1468 NOBUG_RESOURCE_TRY_CTX(flag, resource, user, handle, context)
1470 This is just an alias for RESOURCE_ENTER(flag, resource, user, NOBUG_RESOURCE_TRYING, handle).
1471 Trying on a resource is similar to waiting but will not trigger a deadlock check. This can be used
1472 when a deadlock is expected at runtime and one handles this otherwise (by a timed wait or something like that).
1476 RESOURCE_STATE(flag, entered, state)
1477 NOBUG_RESOURCE_STATE_CTX(flag, state, entered, context)
1478 NOBUG_RESOURCE_STATE_RAW(flagptr, state, entered)
1479 NOBUG_RESOURCE_STATE_RAW_CTX(flagptr, nstate, entered, context)
1481 Changes resource's state.
1484 is nobug flag which turns logging on for this macro
1486 the new state Note that only certain state transitions are
1487 allowed, see discussion/diagram above
1489 the handle set by `RESOURCE_ENTER`
1493 RESOURCE_LEAVE(flag, handle){}
1494 NOBUG_RESOURCE_LEAVE_RAW(flagptr, handle){}
1495 NOBUG_RESOURCE_LEAVE_RAW_CTX(flagptr, handle, context){}
1497 Disconnect from a resource identified with its handle.
1500 nobug flag which turns logging on for this macro
1502 the handle you got while entering the resource
1504 'RESOURCE_LEAVE()' acts like the head of a C loop statement, it ties to the following
1505 (block-) statement. Leaving and the user defined following statement are atomic.
1506 This statement must not be left by break, return or any other kind of jump. NoBug does
1507 not assert this (for for Performance reasons).
1512 NOBUG_RESOURCE_LEAVE(flag, handle)
1514 unlock_my_resource();
1518 [[RESOURCE_ASSERT_STATE]]
1519 .RESOURCE_ASSERT_STATE
1520 RESOURCE_ASSERT_STATE(resource, state)
1521 RESOURCE_ASSERT_STATE_IF(when, resource, state)
1522 NOBUG_RESOURCE_ASSERT_STATE_CTX(resource, state, context)
1523 NOBUG_RESOURCE_ASSERT_STATE_IF_CTX(when, resource, state, context)
1525 Assert that we have a resource in a given state. For multithreaded programms the topmost
1526 state of the calling thread is checked, for non threadeded programs the most recent state on
1530 Condition which must be true for testing the assertion
1538 NOBUG_RESOURCE_DUMP(flag, handle)
1539 NOBUG_RESOURCE_DUMP_IF(when, flag, handle)
1541 Dump the state of a single resource.
1544 Condition which must be true to dump the resource
1546 Nobug flag for the log channel
1548 handle of the resource to be dumped
1550 [[RESOURCE_DUMPALL]]
1552 NOBUG_RESOURCE_DUMPALL(flag)
1553 NOBUG_RESOURCE_DUMPALL_IF(when, flag)
1555 Dump the state of all resources.
1558 Condition which must be true to dump the resources
1560 Nobug flag for the log channel
1564 NOBUG_RESOURCE_LIST(flag)
1565 NOBUG_RESOURCE_LIST_IF(when, flag)
1567 List all registered resources.
1570 Condition which must be true to list the resources
1572 Nobug flag for the log channel
1574 // doc/resourceexample.txt:1 //
1575 .How to use the Resourcetracker
1578 NOBUG_DEFINE_FLAG_LIMIT(test, LOG_DEBUG);
1582 // define a mutex and announce it
1583 pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
1584 RESOURCE_HANDLE(resource);
1586 // 'example' is just a pointer to this function which suffices as unique id
1587 RESOURCE_ANNOUNCE(test, "mutex", "my_mutex", example, resource);
1589 // the following would be done in a different thread in a real program
1591 RESOURCE_HANDLE(enter);
1593 // announce that we want to use the resource
1594 // &enter also suffices as unique pointer, which is all we need as identifer here
1595 RESOURCE_WAIT(flag, resource, &enter, enter)
1597 // lock() might block
1598 pthread_mutex_lock (&my_mutex);
1599 // assume no errors, got it, change the state
1600 RESOURCE_STATE(test, NOBUG_RESOURCE_EXCLUSIVE, enter);
1603 ////////////////////////////////////////
1604 // program does something useful here //
1605 ////////////////////////////////////////
1607 // we don't need it anymore
1608 RESOURCE_LEAVE(test, enter) // << no semicolon
1609 pthread_mutex_unlock (&my_mutex);
1611 // back in the main thread
1612 RESOURCE_FORGET(test, resource); // remove the resource from the public registry
1616 // doc/resourcedeadlock.txt:1 //
1620 The Resource Tracker is able to detect potential deadlocks. This is done by
1621 learning the relations between locks (precedence). A possible deadlock results
1622 in a log message and a fatal abort. Note that only waiting on resources can
1623 lead to a deadlock. Deadlock detection is implemented in the Resource Tracker
1624 and active in ALPHA builds and optimized out on any other build level.
1626 For details about the deadlock detection algorithm see
1627 xref:deadlock_detection[Appendix: Resource Tracking Alorithm].
1629 // src/nobug.h:2301 //
1633 NoBug provides callbacks, applications can use these
1634 to present logging information in some custom way or hook some special processing in.
1635 The callbacks are initialized to NULL and never modified by NoBug, its the solve responsibility
1636 of the user to manage them.
1638 CAUTION: There are certain constraints what and what not can be done in callbacks
1639 documented below which must be followed.
1642 .type of logging callbacks
1643 typedef void (*nobug_logging_cb)(const struct nobug_flag* flag, int priority, const char *log, void* data)
1645 used for the logging callbacks
1648 Flag structure which defines the logging configuration for this event
1650 Log level of the current event
1652 Pointing to the current log line in the ringbuffer or `NULL`
1654 Global pointer defined by the user, passed arround (see below)
1657 .type of abort callback
1658 typedef void (*nobug_abort_cb)(void* data)
1660 used for the abort callback
1663 Global data defined by the user, passed arround (see below)
1666 .passing data to callbacks
1667 void* nobug_callback_data
1669 This global variable is initialized to `NULL` and will never be touched by NoBug. One can use it
1670 to pass extra data to the callback functions.
1672 [[logging_callback]]
1673 .callback when logging
1674 nobug_logging_cb nobug_logging_callback
1676 This callback gets called when something gets logged.
1677 NoBug will still hold its mutexes when calling this hook, calling NoBug logging or resource tracking
1678 functions from here recursively will deadlock and must be avoided.
1679 The `log` parameter points to the logging message in the ringbuffer.
1680 Unlike other logging targets it is not automatically limited to the log level configured
1681 in the flag but called unconditionally. The callback should implement its own limiting.
1683 When one wants to do complex calls which may include recursion into logging and resource tracking
1684 functions, the intended way is to pass contextual information possibly including a __copy__ of the
1685 `log` parameter in xref:THREAD_DATA[NOBUG_THREAD_DATA] to the postlogging callback (see below).
1686 Other internal NoBug facilties, like the ringbuffer etc, are protected by the mutexes and may be accessed
1689 [[postlogging_callback]]
1690 .callback after logging
1691 nobug_logging_cb nobug_postlogging_callback
1693 This callback gets called after something got logged. The `log` parameter is always NULL and all
1694 NoBug mutexes are released. This means that this function may call any complex things, including
1695 calling logging and resource tracking, but may not call internal NoBug facilities.
1696 Contextual created in the `nobug_logging_callback` and stored in xref:THREAD_DATA[NOBUG_THREAD_DATA] can be
1697 retrieved here and may need to be cleaned up here.
1700 .callback for aborting
1701 nobug_abort_cb nobug_abort_callback
1703 This callback gets called when the application shall be terminated due an error.
1704 It can be used to hook exceptions or similar things in. When it returns, `abort()`
1707 IMPORTANT: Errors detected by NoBug are always fatal. If one handles and possible
1708 throws an exception here, the application must shut down as soon as possible.
1709 Most causes for aborts are optimitzed out in `RELEASE` builds.
1711 // src/nobug.h:1540 //
1719 Using this macro one can pass a direct pointer to a flag where a name would
1720 be expected. This is sometimes convinient when flag pointers are passed around
1721 in management strutures and one wants to tie logging to dynamic targets.
1725 NOBUG_DEFINE_FLAG(myflag);
1727 struct nobug_flag* ptr = &NOBUG_FLAG(myflag);
1728 TRACE(NOBUG_FLAG_RAW(ptr), "Passed flag by pointer")
1734 NOBUG_BACKTRACE_CTX(context)
1736 The backtrace macro logs a stacktrace using the NoBug facilities.
1737 This is automatically called when NoBug finds an error and is due
1738 to abort. But one might call it manually too.
1744 This is the default implementation for aborting the program, it first syncs all ringbuffers to disk, then
1745 calls the abort callback if defined and then `abort()`.
1749 If not overridden, evaluates to `NOBUG_ABORT_`. One can override this before including
1750 `nobug.h` to customize abortion behaviour. This will be local to the translation unit then.
1752 [[NOBUG_ALPHA_COMMA]]
1754 NOBUG_ALPHA_COMMA(something)
1755 NOBUG_ALPHA_COMMA_NULL
1757 Sometimes it is useful to have initializer code only in *ALPHA* builds, for example when you
1758 conditionally include resource handles only in *ALPHA* versions. An initializer can then
1759 use this macros to append a comman and something else only in *ALPHA* builds as in:
1760 struct foo = {"foo", "bar" NOBUG_ALPHA_COMMA_NULL };
1765 NOBUG_IF_NOT_ALPHA(...)
1767 NOBUG_IF_NOT_BETA(...)
1768 NOBUG_IF_RELEASE(...)
1769 NOBUG_IF_NOT_RELEASE(...)
1771 This macros allow one to conditionally include the code in '(...)' only if the
1772 criteria on the build level is met. If not, nothing gets substituted. Mostly used
1773 internally, but can also be used for custom things.
1775 // doc/multithreading.txt:1 //
1780 It is important that NoBug protects certain operations with locks in
1781 multithreaded programs. You have to ensure that 'HAVE_PTHREAD_H' is defined by
1782 the configuration system and use the 'libnobugmt' library for linking. It is
1783 particular important that libraries using NoBug are compiled with
1784 'HAVE_PTHREAD_H' enabled when they are intended to be used in multithreaded
1787 When Multithreading is used, log messages contain a identifier of the
1788 originating thread. This identifier should be set by
1791 .NOBUG_THREAD_ID_SET
1792 NOBUG_THREAD_ID_SET(name)
1795 New name for the thread
1797 Nobug will assemble a unique identifier by appending a underscore and a
1798 number to name, for example `NOBUG_THREAD_ID_SET("gui")` will result in a
1799 identifier like "gui_5". When you don't set a thread identifier, then NoBug
1800 assigns one automatically with the name 'thread' preprended if needed. Thread
1801 identifiers may be reset with a new call to this macro.
1804 .NOBUG_THREAD_ID_GET
1807 Will return a const char* of the thread id in multithreaded programs and
1808 a pointer to a literal empty string in singlethreaded programs.
1814 Evaluates to a variable of type `void*` which can be used to store
1815 thread local information. This is useable for xref:_callbacks[callbacks] which may
1816 prepare context information to be reused later.
1818 This macro is also available in singlethreaded programs, refering to a
1819 single global variable.
1821 Nobug initializes this variable to `NULL` and then touches it never again.
1823 // src/nobug_rbdump.c:31 //
1825 Dumping Persistent Ringbuffers
1826 ------------------------------
1828 NoBug installs the `nobug_rbdump` tool for dumping the content of a persistent
1829 ringbuffer. It is invoked with the filename of the ringbuffer, the content is then
1832 // doc/testsuite.txt:1 //
1836 TODO Documentation to be written, use the source Luke!
1838 NoBug maintains a `test.sh` script which drives extensive testsuites.
1839 Look at into the 'tests/' folder about how to apply this.
1841 // doc/bestpractices.txt:1 //
1845 NOTE: this section is very work in progress
1850 * Write a testsuite, build your program with -O0 -g -DEBUG_ALPHA and run
1851 the testsuite under valgrind control. Hack until the program mets the
1852 specifications defined by the testsuite.
1854 * Build with desired optimization level and -g -DEBUG_BETA and give the
1855 program to your beta testers.
1857 * Build it with optimization and without -g -DEBUG_*
1859 .What and when to check
1861 * Add REQUIRE checks on your interfaces (incoming parameters). Especially if
1862 a argument might not cover the whole range of the underlying type.
1863 * Don't waste your and your CPU's time with unnecessary checks. The testsuite
1864 should validate your program. NoBug aids in debugging. You can add
1865 Postconditions (ENSURE) and Invariants when you have a bug somewhere and
1866 want to nail it down.
1867 * Added checks don't need to be removed.
1868 * When you use the CHECKED/UNCHECKED features then don't forget C scoping
1869 rules, tag things as CHECKED from the leaves to the root.
1873 * TRACE(flagname) at the begin of every nontrivial function will easily log
1874 the progress of your application.
1875 * Trying a RELEASE build will abort on certain conditions (known BUG, TODO's,
1876 UNCHECKED code), you can use this to find these spots.
1881 // src/nobug_resources.c:306 //
1882 [[deadlock_detection]]
1883 The Resource Tracking Algorithm
1884 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1886 Each resource registers a global 'resource_record'.
1888 Every new locking path discovered is stored as 'resource_node' structures which refer to the associated
1891 Threads keep a trail of 'resource_user' strcutures for each resource entered. This 'resource_user' struct
1892 refer to the 'resource_nodes' and thus indirectly to the associated 'resource_record'.
1894 The deadlock checker uses this information to test if the acqusition of a new resource would yield a
1897 [[nobug_resource_enter]]
1901 In multithreaded programs, whenever a thread wants to wait for a 'resource_record'
1902 the deadlock checker jumps in.
1904 The deadlock checking algorithm is anticipatory as it will find and abort on conditions which may lead
1905 to a potential deadlock by violating the locking order learned earlier.
1907 Each thread holds a stack (list) of each 'resource_user' it created. Leaving
1908 a resource will remove it from this stacklist.
1910 Each 'resource_record' stores the trail which other 'resource_records' are already entered. This relations
1911 are implemented with the 'resource_node' helper structure.
1914 TODO: insert diagram here
1927 First we find out if there is already a node from the to be acquired resource back to
1928 the topmost node of the current threads user stack.
1931 ---------------------------------------------------------------------
1932 struct nobug_resource_user* user = NULL;
1933 struct nobug_resource_node* node = NULL;
1935 if (!llist_is_empty (&tls->res_stack))
1937 user = LLIST_TO_STRUCTP (llist_tail (&tls->res_stack),
1938 struct nobug_resource_user,
1941 struct nobug_resource_node templ =
1944 user->current->resource,
1948 node = (struct nobug_resource_node*)
1949 llist_ufind (&resource->nodes,
1951 nobug_resource_node_resource_cmpfn,
1955 ---------------------------------------------------------------------
1957 Deadlock checking is only done when the node is entered in `WAITING` state and only
1958 available in multithreaded programs.
1961 ---------------------------------------------------------------------
1962 if (state == NOBUG_RESOURCE_WAITING)
1964 #if NOBUG_USE_PTHREAD
1966 ---------------------------------------------------------------------
1968 If node was found above, then this locking path is already validated and no deadlock can happen,
1969 else, if this stack already holds a resource (user is set) we have to go on with checking.
1972 ---------------------------------------------------------------------
1976 ---------------------------------------------------------------------
1978 If not then its checked that the resource to be entered is not on any parent trail of the current topmost resource,
1979 if it is then this could be a deadlock which needs to be further investigated.
1982 ---------------------------------------------------------------------
1983 LLIST_FOREACH (&user->current->resource->nodes, n)
1985 for (struct nobug_resource_node* itr =
1986 ((struct nobug_resource_node*)n)->parent;
1990 if (itr->resource == resource)
1993 ---------------------------------------------------------------------
1995 if the resource was on the trail, we search if there is a common ancestor before the resource
1996 on the trail and the threads current chain,
1997 if yes then this ancestor protects against deadlocks and we can continue.
2000 ---------------------------------------------------------------------
2001 for (struct nobug_resource_node* itr2 = itr->parent;
2003 itr2 = itr2->parent)
2005 LLIST_FOREACH_REV (&tls->res_stack, p)
2007 struct nobug_resource_user* user =
2008 LLIST_TO_STRUCTP (p,
2009 struct nobug_resource_user,
2011 if (user->current->resource == itr2->resource)
2014 ---------------------------------------------------------------------
2016 If no ancestor found, we finally abort with a potential deadlock condition.
2019 ---------------------------------------------------------------------
2020 nobug_resource_error = "possible deadlock detected";
2023 ---------------------------------------------------------------------
2026 [[nobug_resource_leave]]
2030 store the tail and next aside, we need it later
2033 ---------------------------------------------------------------------
2034 #if NOBUG_USE_PTHREAD
2035 struct nobug_resource_user* tail =
2036 LLIST_TO_STRUCTP (llist_tail (&user->thread->res_stack),
2037 struct nobug_resource_user,
2039 struct nobug_resource_user* next =
2040 LLIST_TO_STRUCTP (llist_next (&user->res_stack),
2041 struct nobug_resource_user,
2043 ---------------------------------------------------------------------
2045 remove user struct from thread stack
2046 The res_stack is now like it is supposed to look like with the 'user' removed.
2047 We now need to fix the node tree up to match this list.
2050 ---------------------------------------------------------------------
2051 llist_unlink_fast_ (&user->res_stack);
2052 ---------------------------------------------------------------------
2054 When the the user node was not the tail or only node of the thread stack, we have to check
2055 (and possibly construct) a new node chain for it. No valdation of this chain needs to be done,
2056 since it was already validated when entering the resources first.
2059 ---------------------------------------------------------------------
2060 if (user != tail && !llist_is_empty (&user->thread->res_stack))
2062 struct nobug_resource_user* parent = NULL;
2063 if (llist_head (&user->thread->res_stack) != &next->res_stack)
2066 LLIST_TO_STRUCTP (llist_prev (&next->res_stack),
2067 struct nobug_resource_user,
2070 ---------------------------------------------------------------------
2072 iterate over all users following the removed node, finding nodes pointing to this users or
2076 ---------------------------------------------------------------------
2077 LLIST_FORRANGE (&next->res_stack, &user->thread->res_stack, n)
2079 struct nobug_resource_user* cur =
2080 LLIST_TO_STRUCTP (n,
2081 struct nobug_resource_user,
2084 ---------------------------------------------------------------------
2085 // src/nobug_resources.c:655 //
2087 find the node pointing back to parent, create a new one if not found, rinse repeat
2090 ---------------------------------------------------------------------
2091 struct nobug_resource_node templ =
2098 struct nobug_resource_node* node = (struct nobug_resource_node*)
2099 llist_ufind (&resource->nodes,
2101 nobug_resource_node_parent_cmpfn,
2106 node = nobug_resource_node_new (resource,
2107 parent?parent->current:NULL);
2110 nobug_resource_error = "internal allocation error";
2118 ---------------------------------------------------------------------
2124 xref:ABORT[Aborting]:: abort the program
2125 xref:abort_callback[callback for aborting]:: hook to handle a termination
2126 xref:abort_cb[type of abort callback]:: type of a abort callback function
2127 xref:ALERT[ALERT]:: about to die
2128 xref:ASSERT[ASSERT]:: generic assertion
2129 xref:assert[assert]:: C standard assertion
2130 xref:BACKTRACE[Backtraces]:: generate a backtrace
2131 xref:buildlevel[Build Levels]:: selecting the build level
2132 xref:callback_data[passing data to callbacks]:: data to be passed to callbacks
2133 xref:CHECK[CHECK]:: unnconditional assertion for testsuites
2134 xref:CHECKED[CHECKED, Scope]:: tag scope as reviewed
2135 xref:Cplusplus_logflags[C++ support, C++ logflags]:: C++ support for log flags
2136 xref:CRITICAL[CRITICAL]:: can not continue
2137 xref:deadlock_detection[The Resource Tracking Algorithm]:: how resources are tracked
2138 xref:DECLARE_FLAG[DECLARE_FLAG]:: declaring a flag
2139 xref:DECLARE_ONLY[DECLARE_ONLY]:: force flag declarations only
2140 xref:DEFINE_FLAG[DEFINE_FLAG]:: defining a flag
2141 xref:DEFINE_FLAG_LIMIT[DEFINE_FLAG_LIMIT]:: defining a flag w/ log limit
2142 xref:DEFINE_FLAG_PARENT[DEFINE_FLAG_PARENT]:: defining a flag hierarchy
2143 xref:DEFINE_FLAG_PARENT_LIMIT[DEFINE_FLAG_PARENT_LIMIT]:: defining a flag hierarchy, w/ log limit
2144 xref:DEPRECATED[DEPRECATED]:: to be discarded in future
2145 xref:DUMP[DUMP]:: dumping datastructures
2146 xref:DUMP_LOG[DUMP_LOG]:: logging helper for dumping
2147 xref:ECHO[ECHO]:: unconditional logging for tests
2148 xref:ELSE_NOTREACHED[ELSE_NOTREACHED]:: alternative never taken
2149 xref:ENSURE[ENSURE]:: postconditions (computation outcomes)
2150 xref:ERROR[ERROR]:: something gone wrong
2151 xref:FIXME[FIXME]:: known bug
2152 xref:INFO[INFO]:: progress message
2153 xref:INJECT_FAULT[INJECT_FAULT]:: fault injection statement
2154 xref:INJECT_GOODBAD[INJECT_GOODBAD]:: fault injection expression
2155 xref:INJECT_LEVEL[INJECT_LEVEL]:: log level for fault injection
2156 xref:INVARIANT[INVARIANT]:: validate invariant state
2157 xref:LOG[LOG]:: generic logging
2158 xref:LOG_BASELIMIT[LOG_BASELIMIT]:: minimum compliled-in logging limit
2159 xref:logflags[Log Flags]:: define hierarchies for logging output
2160 xref:logging_callback[callback when logging]:: hook when something get logged
2161 xref:logging_cb[type of logging callbacks]:: type of a logging callback function
2162 xref:multithreading[Multithreading]:: using NoBug in multithreaded programs
2163 xref:NOBUG_ALPHA_COMMA[NOBUG_ALPHA_COMMA]:: append something after a comma in *ALPHA* builds
2164 xref:NOBUG_ANN[NOBUG_ANN]:: log flag for annotations
2165 xref:NOBUG_CONTEXT[Source Contexts]:: pass information about the source location
2166 xref:NOBUG_ENV[Control what gets logged]:: environment variable for loging control
2167 xref:nobug_flag[nobug (flag)]:: log flag used to show nobug actions
2168 xref:NOBUG_FLAG_RAW[NOBUG_FLAG_RAW]:: pass direct flag pointer
2169 xref:NOBUG_IF[NOBUG_IF_*]:: include code conditionally on build level
2170 xref:NOBUG_ON[NOBUG_ON]:: log flag which is always enabled
2171 xref:nobug_resource_enter[Entering Resources]:: deadlock check on enter
2172 xref:nobug_resource_leave[Leaving Resources]:: fix resource lists
2173 xref:NOTICE[NOTICE]:: detailed progress message
2174 xref:NOTREACHED[NOTREACHED]:: code path never taken
2175 xref:PLANNED[PLANNED]:: ideas for future
2176 xref:postlogging_callback[callback after logging]:: hook after something get logged
2177 xref:rbdump[Dumping Persistent Ringbuffers]:: dumping persistent ringbuffers
2178 xref:REQUIRE[REQUIRE]:: preconditions (input parameters)
2179 xref:RESOURCE_ANNOUNCE[RESOURCE_ANNOUNCE]:: publish new resources
2180 xref:RESOURCE_ASSERT_STATE[RESOURCE_ASSERT_STATE]:: assert the state of a resource
2181 xref:RESOURCE_DUMP[RESOURCE_DUMP]:: dump the state of a single resource
2182 xref:RESOURCE_DUMPALL[RESOURCE_DUMPALL]:: dump the state of all resources
2183 xref:RESOURCE_ENTER[RESOURCE_ENTER]:: claim a resource
2184 xref:RESOURCE_FORGET[RESOURCE_FORGET]:: remove resources
2185 xref:RESOURCE_HANDLE[RESOURCE_HANDLE]:: define resource handles
2186 xref:RESOURCE_LEAVE[RESOURCE_LEAVE]:: relinquish a claimed resource
2187 xref:RESOURCE_LIST[RESOURCE_LIST]:: enumerate all registered resources
2188 xref:RESOURCE_LOG_LEVEL[RESOURCE_LOG_LEVEL]:: select the log level for resource logging
2189 xref:RESOURCE_LOGGING[RESOURCE_LOGGING]:: switch resource logging on and off
2190 xref:RESOURCE_STATE[RESOURCE_STATE]:: change the state of a resource
2191 xref:RESOURCE_TRY[RESOURCE_TRY]:: wait for a resource to become available
2192 xref:RESOURCE_WAIT[RESOURCE_WAIT]:: wait for a resource to become available
2193 xref:THREAD_DATA[NOBUG_THREAD_DATA]:: thread local data for application use
2194 xref:THREAD_ID_GET[NOBUG_THREAD_ID_GET]:: query thread id
2195 xref:THREAD_ID_SET[NOBUG_THREAD_ID_SET]:: set or reset thread id
2196 xref:TODO[TODO]:: things to be done
2197 xref:TRACE[TRACE]:: debugging level message
2198 xref:UNCHECKED[UNCHECKED, Scope]:: tag scope as unreviewed
2199 xref:UNIMPLEMENTED[UNIMPLEMENTED]:: not yet implemented
2200 xref:WARN[WARN]:: unexpected fixable error
2202 // doc/license.txt:1 //
2207 Copyright (C) 2009 Christian Thäter <ct@pipapo.org>
2209 This program is free software; you can redistribute it and/or modify
2210 it under the terms of the GNU General Public License as published by
2211 the Free Software Foundation; either version 2 of the License, or
2212 (at your option) any later version.
2214 This program is distributed in the hope that it will be useful,
2215 but WITHOUT ANY WARRANTY; without even the implied warranty of
2216 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2217 GNU General Public License for more details.
2219 You should have received a copy of the GNU General Public License along
2220 with this program; if not, write to the Free Software Foundation, Inc.,
2221 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2225 NoBug is released under the "GNU General Public License version 2 or
2226 any later" to protect its freedom. If one wants to use NoBug in a
2227 propietary program, please contact the main author for
2228 acknowledging relicensing terms.
2230 For BSD license style Free Software, this means you can not distribute
2231 binaries linking NoBug without making its source available. To make
2232 this compatible, it is suggested that you dual-license your software
2233 with your prefered BSD like license and the GPL. As long as it uses
2234 NoBug, the GPL will take over and you have to make the source
2235 available, while one can ship a BSD or LGPL Licensed headerfile which
2236 defines all NoBug macros as empty macros and remove libnobug from the
2237 linking, then NoBug isn't used anymore and you may apply BSD license
2238 terms for resulting binaries.
2241 Contributor Agreement
2242 ~~~~~~~~~~~~~~~~~~~~~
2244 Improvements and patches must be licensed as "GPL v2 or any later" to
2245 be acceptable. Further a contributor must either assign his copyright
2246 to the main NoBug author or agree with the possibility that NoBug can
2247 be relicensed for propietary use:
2249 Independent of the GPL license as stated above, The main author of
2250 NoBug explicitly reserve the right to relicense NoBug under
2251 different, even propietary terms. Any contributor agrees to such
2252 a possiblility by sending his contribution to be included into
2253 the official releases.
2255 This agreement is bilateral, every contributor who worked on a
2256 substantial part of NoBug has the right to relicense it after
2257 negotiation with the NoBug main author. Exact terms of such
2258 relicensing are worked out on a per case base.
2260 The intention is that anyone who worked on NoBug should be able to
2261 benefit from his work. This means one should be able to use it at his
2262 workplace, to gain a job or as well as relicense it for a customer.
2263 Unlike other projects which simply ask for transfering the copyright
2264 to the main author, NoBug tries to make it possible to retain the
2265 copyright by anyone who helped the project.
2267 This additional agreement has no impact on the GPL, it's sole purpose
2268 is to define relicensing policies between the NoBug main author and
2269 contributors. When you recieve NoBug it will be licensed under
2270 GPL unless you personally acknowledged other terms with the NoBug main
2271 author (or any other main contributor).
2273 If anyone feels he is not credited in the 'AUTHORS' file or in any
2274 copyright notice, please contact the main author for inclusion.