fix some stupid bugs
[nobug.git] / README
blob7b992fd6855e88a8855683ddcd0f625581208002
1 NOBUG Documentation
3   * "Everyone makes errors, but with NoBug you won't make them twice!"
5 Nobug is a simple debugging library for instrumenting C and C++ programs
6 inspired from Design-by-Contract ideas.
8 Overview
10 NoBug provides you with the following:
12   * Three different levels for checks - in depth to final no-overhead
13   * Scope tags - tell whenever a function or loop is considered to be bug free
14   * Preconditional, Postcondition and Invariant checks, generic Assertions
15   * Debugger support (actions are only executed while running under a
16     debugger), currently only valgrind
17   * Dumping of your datastructures
18   * Logging your application's activities
19   * Runtime customizable logging via an enviromnet variable
20   * Different logging targets (stderr, syslog, debugger...)
21   * Annotation of your sourcecode about known bugs, things to do, etc.
22   * Tracking Resources (Files, Locks, etc.) used by your programm; help in
23     detecting misuse.
25 In contrast to traditional debuggers, NoBug is a non-interactive debugger which
26 is linked to your application doing hard-coded tests in a efficient,
27 low-overhead way.
29 Building and Installing
31 Release Tarballs
33 Release tarballs are attached to this wiki at:
35   * http://pipawiki/NoBug?action=AttachFile
37 I am using gpg signed tarballs for distribution. As first step one has to check
38 the signature
40 $ gpg nobug-X.Y.tar.gz.gpg
42 This will produce a nobug-X.Y.tar.gz and report if the signature could be
43 validated.
45 Since they are built with gnu autotools, the usual build and install procedure
46 works:
48 $ tar xzvf nobug-X.Y.tar.gz
49 $ cd nobug-X.Y
50 $ ./configure
51 $ make
52 $ make install
54 Development Version via git
56 The devlopment version is available via git from 'git://git.pipapo.org/nobug'
57 or mirrored at repo.or.cz 'git://repo.or.cz/nobug.git'.
59 After you cloned the repository you need to bootstap the autotools first
61 $ autoreconf -i
63 Then the usual ./configure && make && make install will work.
65 There is a special makefile target make meta to bring serveral files (README,
66 AUTHORS, NEWS) in sync with the NoBug Documentation wiki and update the
67 ChangeLog.
69 What gets installed
71 Currently, NoBug installs the following:
73   * A single nobug.h headerfile which your code will use
74   * Two libs for static linking:
75       + 'libnobug.a' for singlethreaded programs
76       + 'libnobugmt.a' for multithreaded programs.
78 Using NoBug
80 You can make Nobug features available either by installing it as described
81 above or by shipping the nobug sources along with your project.
83 To use NoBug, some controling preprocessor macros have to be defined. The
84 nobug.h header should then be included.
86 A project using NoBug should use autoconf to check for execinfo.h and valgrind/
87 valgrind.h
89 AC_CHECK_HEADERS([execinfo.h valgrind/valgrind.h])
91 For Multithreaded programs, you should also check for pthread.h.
93 When the resulting HAVE_PTHREAD_H, HAVE_EXECINFO_H and HAVE_VALGRIND_VALGRIND_H
94 are defined by the configure script, the corresponding features become
95 available.
97 NoBug then defines 'NOBUG_USE_PTHREAD', 'NOBUG_USE_VALGRIND' and
98 'NOBUG_USE_EXECINFO' to 1. If you do not want to use any of these features in
99 NoBug, you can define these macros to 0 before including nobug.h.
101 If NVALGRIND is defined, valgrind support will not be used.
103 There are many other macros which can be set and overridden by the user to
104 control the behavior. Please edit the Documentation wiki when you find them
105 useful.
107 A program using NoBug should be linked against 'libnobug.a' if it is
108 singlethreaded or against 'libnobugmt.a' if it is multithreaded. The Library
109 must be initialized with NOBUG_INIT before using any other features or creating
110 threads. This is discussed in more detail at NoBug/Documentation/Macros/
111 MultiThreading.
113 Debug Control
115 Build Levels
117 Nobug uses the following different levels of checks:
119   * ALPHA
120       + for expensive testing and logging while developing the software
121     BETA
122       + for testers and users who want to try the software
123     RELEASE
124       + finished version for end users
126 Release builds remove all assertions, but some logging is kept. We make the
127 assumption that bugs which where not covered in alpha and beta builds will not
128 easily show up in releases because the assertions there where not sufficent.
129 Further, end users are not test bunnies and will not provide good bug reports
130 anyway. If there is a problem in a release build, try to investigate the cause
131 with a beta build from the same source.
133 To define a debug level for compilation, just use '-DEBUG_ALPHA' or
134 '-DEBUG_BETA' for bebug builds and use the standard '-DNDEBUG' for a release
135 build. Nobug will complain if the debug level has not been defined.
137 Scope Checks
139 The programmer can tag any Scope as UNCHECKED or CHECKED. In ALPHA and BETA
140 builds, a global UNCHECKED is implied. In RELEASE builds, UNCHECKED Scopes are
141 not allowed.
143 Test Matrix
145 Here is a table of which basic assertions gets checked on each level/scope
146 combination:
148           ALPHA                          BETA                   RELEASE
149 UNCHECKED Preconditions, Postconditions, Preconditions,         compiling will
150           Invariants                     Postconditions         abort
151 CHECKED   Preconditions, Postconditions  Preconditions
153 Macros
155 The NoBug interface is almost completely implemented in preprocessor macros.
156 This is needed because it uses the __FILE__ and __LINE__ macros for logging.
157 All of the flat namespace uppercase identifiers make it easily recognizeable
158 within source code too.
160 All macros are unconditionally available with NOBUG_ prefixed. For convenience,
161 there are also macros without this prefix as long as such a macro was not
162 already defined. For each Assertion and Logging macro, there is a form with the
163 suffix _DBG which will be only active under a debugger. The _DBG versions are
164 only enabled in alpha builds.
166 When NOBUG_DISABLE_SHORTNAMES is defined by the user, then only the NOBUG_
167 prefixed macros are available and the short ones will never be defined.
169 There are also assertions with an _IF suffix taking a 'when' parameter as first
170 argument. The following is an example:
172   * REQUIRE_IF(foo!=NULL, foo->something == constrained)
174 The assertion will only be performed when when is true. The debugger versions
175 are available as _IF_DBG prefixed macros.
177 Parameters types:
179 when    Assertion is only performed if expression 'when' is true at runtime
180 expr    Test without side effects
181 fmt     printf like formatstring
182 ...     If not preceeded by 'fmt', then printf like formatstring. Otherwise,
183         only its arguments
184 flag    Flag for enabling custom logging groups
185 type    Type of the data to be checked as a single identifier name
186 pointer Pointer to type
187 lvl     Log level
188 depth   Depth for invariants and dumps
190 Initialization
192 Global init
194 You have to call
196   * NOBUG_INIT
198 before using any other NoBug feature. Probably in main or any other library
199 initialization routine. Calling NOBUG_INIT more than once is supported and each
200 subsequent call will be a no-op, thus initialization in main and in libraries
201 won't interfere.
203 Control Flags
205 If you want to use environment variable controlled debuging, then you have to
206 initialize each flag with
208   * NOBUG_INIT_FLAG(flagname)
212   * NOBUG_INIT_FLAG_LIMIT(flagname, default)
214 This is documented later in NoBug/Documentation/Macros/LoggingConfiguration.
216   * <!> These two macros call NOBUG_INIT for backward compatibility.
218 Threads
220 In Multithreaded programs you should assign an identifier to each thread after
221 it is created with
223   * NOBUG_THREAD_ID_SET(name)
225 If you don't call it, then NoBug will assign a automatic identifier. This is
226 documented in NoBug/Documentation/Macros/MultiThreading.
228 Assertions
230   * REQUIRE(expr, ...)
231       + Precondition (input) check. Use these macros to validate input a
232         function recieves. The checks are enabled in ALPHA and BETA builds and
233         optimized out in RELEASE builds.
235     ENSURE(expr, ...)
236       + Postcondition (progress/output) check. Use these macros to validate the
237         data a function produces (example: return value). The checks enabled
238         unconditionally in ALPHA builds and optimized out in BETA builds for
239         scopes which are tagged as CHECKED. In RELEASE builds this checks are
240         always optimized out, but scopes tagged as UNCHECKED are not permitted.
242     ASSERT(expr, ...)
243       + Generic check. Use these macros when you want to validate something
244         which doesn't fall into one of the above categories. A example is when
245         a library function can return a unexpected result (scanf with syntax
246         error in the formatstring, when a constant/literal formatstring is
247         expected). The checks are enabled in ALPHA and BETA builds and
248         optimized out in RELEASE builds.
250     assert(expr)
251       + Nobug overrides the standard assert macro in ALPHA and BETA builds.
252         This is just a compatibility feature, its use is not suggested.
254     INVARIANT(type, pointer, depth)
255       + Checking invariants. You can provide more complex checking functions
256         which test the validity of datastructures. Invariants are only enabled
257         in ALPHA builds for scopes which are not tagged as CHECKED and
258         otherwise optimized out. (TODO: document how to write invariants)
260 Logging
262 Nearly all NoBug Macros emit some log message. NoBug gives the user fine
263 grained control over these log messages to display only interesting information
264 without loosing details.
266 Log messages are routed to different destinations which are:
268   * RINGBUFFER
269       + The underlying storage backend. Messages are appended to the end of the
270         buffer, overwriting older messages at the front of the buffer. NoBug
271         comes with a highly efficent ringbuffer implementation.
272   * CONSOLE
273       + This is either just stderr or if running under valgrind then valgrind
274         facilities to include messages into its log will be used.
275   * FILE
276       + The user can open Files for log messages.
277   * SYSLOG
278       + Messages are send to the standard system logging daemon.
279   * APPLICATION
280       + There is a interface which allows the programmer to catch logmessages
281         and display them in a application defined way.
283 Each logmessage has a priority descibing its severity in the same way as syslog
284 messages do.
286 All non-fatal messages are associated with a programmer defined flag describing
287 the source of the message (subsystem, module, ...).
289 Putting it all together: A user can define which source/flag shall be logged at
290 what priority level and to which destination. To make this all easier NoBug
291 tries to give reasonable defaults.
293 Configuration
295 Log Levels
297 Each Log macro has a explicit or implicit Log-Level which correspondends to
298 syslog levels. Logging is only emitted when the messages is more servere than a
299 defined limit.
301 The defaults look like:
303             ALPHA BETA    RELEASE
304 ringbuffer  TRACE INFO    NOTICE  ringbuffer must always be most verbose
305 console     INFO  NOTICE  -1      no log to console in release
306 file        TRACE NOTICE  WARNING
307 syslog      -1    NOTICE  WARNING no syslog for test runs
308 application INFO  WARNING ERROR
310 Depending on the build level there is a default logging target and a default
311 limit which is choosen when the user doesn't specify one.
313 The default limits are:
315   * In ALPHA builds, NOBUG_LOG_LIMIT_ALPHA is used which defaults to LOG_INFO
316   * In BETA builds, NOBUG_LOG_LIMIT_BETA is used and defaults to LOG_WARNING
317   * In RELEASE builds, NOBUG_LOG_LIMIT_RELEASE is used and defaults to LOG_CRIT
319 The default targets are:
321   * In ALPHA builds, NOBUG_LOG_TARGET_ALPHA is used which defaults to
322     NOBUG_TARGET_CONSOLE
323   * In BETA builds, NOBUG_LOG_TARGET_BETA is used and defaults to
324     NOBUG_TARGET_FILE
325   * In RELEASE builds, NOBUG_LOG_TARGET_RELEASE is used and defaults to
326     NOBUG_TARGET_SYSLOG
328 You can override all of those values with your own preference. Alternatively
329 NOBUG_LOG_LIMIT and NOBUG_LOG_TARGET can be defined by the user to override all
330 defaults.
332 Log Flags
334 Flags are used to tell NoBug about subsystems/modules or even finer grained
335 parts of the code.
337 A Flag should be declared with
339   * NOBUG_DECLARE_FLAG(flagname)
341 preferably in one of your headers
343 Further it must be defined with
345   * NOBUG_DEFINE_FLAG(flagname)
349   * NOBUG_DEFINE_FLAG_LIMIT(flagname, limit)
351 in one of your source files
353 Next you should call
355   * NOBUG_INIT_FLAG(flagname)
359   * NOBUG_INIT_FLAG_LIMIT(flagname, default)
361 once at the start of your program for every flag.
363 For flags defined with NOBUG_DEFINE_FLAG(flagname) the defaults are initialized
364 as in the table above, while NOBUG_DEFINE_FLAG_LIMIT(flagname, level) is used
365 to initialize the default target (depending on build level) to limit. Calling
366 NOBUG_INIT_FLAG(flagname) is optional for limit initialized flags.
368 NOBUG_INIT_FLAG(flagname) parses the environment variable '$NOBUG_LOG' for
369 flagname, the syntax is as following:
371 logdecl_list --> logdecl, any( ',' logdecl_list).
373 logdecl --> flag, opt(limitdecl, any(targetdecl))
375 flag --> "identifier of a flag"
377 limitdecl --> ':', "LIMITNAME"
379 targetdecl --> '@', "targetname", opt(targetopts)
381 targetopts --> '(', "options for target", ')', opt(targetopts)
383 Roughly speaking, NOBUG_LOG contains a comma separated list of declarations for
384 flags which are the name of the flag followed by a limit which is written in
385 all uppercase letters and preceeded by a colon, followed by target declarations
386 which are names of the targets, introduced by a at sign. Target declarations
387 can have options in future which is not yet implemented. Limit and target
388 declarations are optional and then choosen from the defaults table above. These
389 defaults are currently just an guess what should be useable and might be
390 redefined in future.
392 <!> NOTE: '(options)' on targets are not yet implemented!
394 Examples:
396 NOBUG_LOG='flag,other'                        # set the limit of the default target a default limit (see table above)
397 NOBUG_LOG='flag:DEBUG'                        # set the limit of the default target to DEBUG
398 NOBUG_LOG='flag:DEBUG@console@syslog'         # set console and syslog limits for flag to DEBUG
399 NOBUG_LOG='flag:DEBUG,other:TRACE@ringbuffer'
401 There is a predefined flag NOBUG_ON which is always enabled.
403 Example code:
405    1 #include "nobug.h"
406    2 NOBUG_DEFINE_FLAG (test);
407    3
408    4 int
409    5 main()
410    6 {
411    7   NOBUG_INIT_FLAG (test);
412    8
413    9   INFO (test, "Logging enabled");
414   10   INFO (NOBUG_ON, "Always on");
415   11 }
417 test it:
419 $ tcc -DEBUG_ALPHA -run example.c
420 example.c:10: debug: INFO: main: Always on
422 $ NOBUG_LOG=test tcc -DEBUG_ALPHA -run example.c
423 example.c:9: debug: INFO: main: Logging enabled
424 example.c:10: debug: INFO: main: Always on
426 The Logging Macros
428 These macros log with implicit Log Level, note that there are no more servere
429 levels than LOG_ERROR since these should be handled by Assertions in a
430 debugging library.
432   * ERROR(flag, fmt, ...)
433     ERROR_IF(expr, rflag, fmt, ...)
434       + Application takes a error handling brach
436     WARN(flag, fmt, ...)
437     WARN_IF(expr, flag, fmt, ...)
438       + Rare, handled but unexpected branch
440     INFO(flag, fmt, ...)
441     INFO_IF(expr, flag, fmt, ...)
442       + Message about program progress
444     NOTICE(flag, fmt, ...)
445     NOTICE_IF(expr, flag, fmt, ...)
446       + More detailed
448     TRACE(flag, fmt, ...)
449     TRACE_IF(expr, flag, fmt, ...)
450       + Very fine grained messages
452 Note that TRACE correspondends to LOG_DEBUG, using 'DEBUG' could be ambiguous.
454 There is one generic LOG macro which takes the level explicitly:
456   * LOG(flag, lvl, fmt, ...)
457     LOG_IF(expr, flag, lvl, fmt, ...)
459 Dumping Datastructures
461   * DUMP(flag, type, pointer, depth)
462       + Dump a datastructure
463     DUMP_IF(expr, flag, type, pointer, depth)
464       + Dump datastructure if expr is true
466 How to write DUMP handlers
468 if you have a
470    1 struct STRUCTNAME
471    2 {
472    3   int INTEGER_MEMBER;
473    4   char * STRING_MEMBER;
474    5   struct STRUCTNAME* next;
475    6 }
477 then you define a function like:
479    1 void
480    2 nobug_STRUCTNAME_dump (const struct STRUCTNAME* self,
481    3                        const int depth,
482    4                        const char* file,
483    5                        const int line,
484    6                        const char* func)
485    7 {
486    8   // check for self != NULL and that the depth
487    9   // limit did not exceed in recursive datastructures
488   10   if (self && depth)
489   11   {
490   12     // use DUMP_LOG not LOG to print the data
491   13     DUMP_LOG("STRUCTNAME %p: int is %d, string is %s", self,
492   14                              self->INTEGER_MEMBER,
493   15                              self->STRING_MEMBER);
494   16     // now recurse with decremented depth
495   17     nobug_STRUCTNAME_dump (self->next, depth-1, file, line, func);
496   18   }
497   19 }
499 now you can use the DUMP() macros within the code
501    1 example()
502    2 {
503    3   struct STRUCTNAME foo;
504    4   init(&foo);
505    5   DUMP (my_flag, STRUCTNAME, &foo, 2);
506    6 }
508 Dumping is by default done on level LOG_DEBUG, this can be overridden by
509 defining NOBUG_DUMP_LEVEL to some other level, further DUMP_IF is the only
510 enabled dumping macro for the RELEASE build level.
512 Source Annotations
514 One can tagging features as:
516   * DEPRECATED(...)
517       + Something which shouldn't be used in future.
518     UNIMPLEMENTED(...)
519       + important, not yet finished feature
520     PLANNED(...)
521       + planned for future feature
522     FIXME(...)
523       + known bug to be fixed later
524     TODO(...)
525       + enhancement to be done soon
526     NOTREACHED
527       + used to tag code-path which shall be never executed (defaults in switch
528         statements, else NOTREACHED after series of if's)
530 The advantage of this tagging over plain source comments is that we can take
531 some actions if we run in such a tag at compile or runtime:
533 the action to be taken when such a macro is hit depends on the build level:
535               ALPHA BETA         RELEASE
536 DEPRECATED    log   nothing      wont compile
537 UNIMPLEMENTED abort abort        wont compile
538 FIXME         log   wont compile wont compile
539 TODO          log   log          wont compile
540 PLANNED       log   nothing      nothing
541 NOTREACHED    abort abort        removed
543 Legend:
545   * abort means first log and then abort
546   * log will only log once for each sourceline (not on each hit)
547   * wont compile will abort compilation with a error message
548   * nothing optimized out, sane way
549   * removed optimized out for performance reasons
551 Resource Tracking
553 With little effort, NoBug can watch all kinds of resources a program uses. This
554 becomes useful for resources which are distributed over a multithreaded
555 program. Resource tracking is only active in ALPHA builds and optimized out in
556 BETA and RELEASE builds.
558 Concepts
560 Resources are abstracted, NoBug has little knowledge about the semantics of a
561 resource, it only keeps records of resources and the code using it and ensures
562 basic constraints. Detailed usage checks of resource have to be done with other
563 NoBug facilities.
565 Resources are identified by a arbitary identifier which is just a pointer and
566 if using threads, NoBug's thread identifier. Additionaly a name, the type and
567 the source locations which anounced the resource are stored.
569 Code which wants to use a resource calls a enter macro with its own identifier
570 and state, then might alter the state and finally a leave macro when finished
571 with it.
573 When a resource is used one has to pass one of three states:
575   * NOBUG_RESOURCE_WAITING
576       + For resources where acquisition could block (locks) you enter it with a
577         WAITING state and as soon you aacquired it you change the state to one
578         of the following.
579   * NOBUG_RESOURCE_EXCLUSIVE
580       + Acquired the resource exclusively, this means for NoBug that trying to
581         get the resource again with the same identifier would be fatal, other
582         parts of the program could still enter it.
583   * NOBUG_RESOURCE_RECURSIVE
584       + The resource might be entered multiple times from the same identifier,
585         NoBug keeps a reference count and only deletes the record when the
586         resource is left as much times the state was changed to
587         NOBUG_RESOURCE_RECURSIVE
589 Possible state transistions:
591   * [ResourceTr]
593 The macros
595 Resources are accessed through handles, these handles are defined with
597   * RESOURCE_HANDLE(name)
599 This macro takes care that the declaration is optimized out in the same manner
600 the rest of the resource tracker would be disabled. You can still instantiate
601 handles as struct nobug_resource_record* in structures which must have a
602 constant size unconditional of the build level.
604 Resources are published by
606   * RESOURCE_ANNOUNCE(flag, type, name, identifier, handle)
608 Resources must be unique, it is a fatal error when a resource it tried to be
609 announced more than one time.
611   * 'flag' is nobug flag which turns logging on for this macro.
612   * 'type' is a cstring which should denote the domain of the resource, the
613     type "nobug" is reserved for internal use. Other strings are freely
614     chooseable, examples are "file" "mutex" "lock" "database" and so on.
615   * 'name' is the actual name of a named resource this is a cstring which
616     together with type forms a unique identifier of the resource. 'type' and
617     'name' must be available through the entire lifetime of the resource, using
618     literal strings is recommended.
619   * 'identfier' is a pointer which should be unique for this resource, any kind
620     of pointer will suffice, it is only used for identification. In
621     multithreaded applications the thread identifier becomes an additional
622     identifier.
623   * 'handle' is a nobug_resource_record* which will be initialized to point to
624     the newly created resource.
626 When a resource becomes unavailable it is removed from the registry by
628   * RESOURCE_FORGET(flag, handle)
630 The resource must still exist and no users must be attacched to it, else a
631 fatal error is raised.
633 Code which wants to use a resource attaches to it by
635   * RESOURCE_ENTER(flag, announced, name, identifier, state, handle)
636   * 'flag' is nobug flag which turns logging on for this macro.
637   * 'announced' is the handle set by RESOURCE_ANNOUNCE
638   * 'name' is a free-form identifier
639   * 'identifier' is some pointer which must be unique for the user of the
640     resource (see above)
641   * 'state' is the initial state, one of NOBUG_RESOURCE_WAITING,
642     NOBUG_RESOURCE_EXCLUSIVE or NOBUG_RESOURCE_RECURSIVE
643   * 'handle' is a nobug_resource_record* which will be initialized to the
644     entering node.
646 For some uses one can change the state with
648   * NOBUG_RESOURCE_STATE(flag, entered, state)
649   * 'flag' is nobug flag which turns logging on for this macro.
650   * 'entered' is the handle set by RESOURCE_ENTER
651   * 'state' is the new state Note that only certain state transisitons are
652     allowed, see discussion/diagram above
654 When finished with using the resource you dissconnect from it either with the
655 handle you initialzed when entering it
657   * RESOURCE_LEAVE(flag, handle)
658   * 'flag' is nobug flag which turns logging on for this macro.
659   * 'handle' is the handle you got while entering the resource.
661 or by looking it up in the announced resource by its identifier
663   * RESOURCE_LEAVE_LOOKUP(flag, resource, identifier)
664   * 'flag' is nobug flag which turns logging on for this macro.
665   * 'resource' is the handle you got from announcing the resource.
666   * 'identifier' is the pointer you gave it when creating it
668 Resources keep track of the thread which used them, you cant ANNOUNCE/FORGET
669 ENTER/LEAVE the same handle from different threads.
671 Just a simple example:
673    1 NOBUG_DEFINE_FLAG_LIMIT(test, LOG_DEBUG);
674    2
675    3 void example()
676    4 {
677    5
678    6   // define a mutex and announce it
679    7   pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
680    8   RESOURCE_HANDLE(resource)
681    9   // 'example' is just a pointer to this function which suffices as unique id
682   10   RESOURCE_ANNOUNCE(test, "mutex", "my_mutex", example, resource);
683   11
684   12   // the following would be actually done in a different thread in a real program
685   13   RESOURCE_HANDLE(test, enter);                            // define a handle
686   14   RESOURCE_ENTER_NAME(test, resource, "example", &enter, NOBUG_RESOURCE_WAITING, enter);
687   15                                                            // announce that we want to use the resource
688   16                                                            // &enter also suffices as unique pointer
689   17   pthread_mutex_lock (&my_mutex);                          // this might block
690   18   RESOURCE_STATE(test, enter, NOBUG_RESOURCE_EXCLUSIVE);   // we got it, now announce that
691   19
692   20   // program does something useful here
693   21
694   22
695   23   pthread_mutex_lock (&my_mutex);                          // and instantly unlock
696   24   RESOURCE_LEAVE(test, enter);                             // we don't need it anymore
697   25
698   26   // back in the main thread
699   27   RESOURCE_FORGET(test, resource);                         // remove the resource from the public registry
700   28 }
702 Logging Control
704 Unless the user defines NOBUG_RESOURCE_LOGGING to 0 each of the above macros
705 will emit a log message at NOBUG_RESOURCE_LOG_LEVEL which defaults to
706 LOG_DEBUG.
708 Notes
710 The Resource Tracker is neither bullet-proof nor exact. There are small race
711 conditions in the time we announce/forget/enter/remove resources and doing the
712 actual call to a resource. These race conditions affect the reporting exactness
713 and are a design decision, for practical use they are no danger.
715 More important is that the Resource Tracker relies on that announce/forget and
716 enter/leave are properly paired. The programmer should ensure that this is done
717 right, else it will become unuseable. This will be fixed in future NoBug
718 versions.
720 The underlying resource-tracking library may report errors, all these errors
721 are fatal for NoBug and trigger an abort(). When such an error occurs the
722 Resource Tracker is left in a locked state, which is harmless and intended for
723 generating reports prior the abort.
725 Multithreading
727 It is important that NoBug protects certain operations with locks in
728 multithreaded programs. You have to ensure that 'HAVE_PTHREAD_H' is defined by
729 the configuration system and use the 'libnobugmt.a' library for linking. It is
730 particular important that libraries using NoBug are compiled with
731 'HAVE_PTHREAD_H' enabled when they are intended to be used in multithreaded
732 programs.
734 When Multithreading is used, log messages contain a identifier of the
735 orginating thread. This identifier should be set by
737   * NOBUG_THREAD_ID_SET(name)
739 right after thread creation. name is a string describing the purpose of the
740 thread. Nobug will assemble a unique identifier by appending a underscore and a
741 number to name, for example NOBUG_THREAD_ID_SET("gui") will result in a
742 identifier like "gui_5". When you don't set a thread identifier, then NoBug
743 assigns one automatically with the name 'thread' preprended if needed. Thread
744 identifiers are immutable once set.
746 For querying the thread identifier you use
748   * NOBUG_THREAD_ID_GET
750 which will return a const char* to the thread id in multithreaded programms and
751 a pointer to a literal "" in singlethreaded programs.
753 Tool Macros
755   * BACKTRACE(...)
756       + Log a stacktrace
757     ABORT
758       + just calls abort()
760 Best Practices
762 <!> this section is very work in progress
764 Workflow
766  1. Development
767       + Write a testsuite, build your program with -O0 -g -DEBUG_ALPHA and run
768         the testsuite under valgrind control. Hack until the program fits the
769         requirements defined by the testsuite.
770  2. Beta Test
771       + Build with desired optimization level and -g -DEBUG_BETA and give the
772         program to your beta testers.
773  3. Release
774       + Just build it with optimization and without -g -DEBUG_*
776 What and when to check
778   * Add REQUIRE checks on your interfaces (incoming parameters). Especially if
779     a argument might not cover the whole range of the underlying type.
780   * Don't waste your and your CPU's time with unessesary checks. The testsuite
781     should validate your program. NoBug aids in debugging. You can add
782     Postconditions (ENSURE) and Invariants when you have a bug somewhere and
783     want to nail it down.
784   * Added checks don't need to be removed.
785   * When you use the CHECKED/UNCHECKED features then don't forget C scoping
786     rules, tag things as CHECKED from the leaves to the root.
788 Tips & Tricks
790   * TRACE(flagname) or TRACE_DBG(flagname) at the begin of every nontrivial
791     function will easily log the progress of your application.
792   * Trying a RELEASE build will abort on certain conditions (known BUG, TODO's,
793     UNCHECKED code), you can use this to find these spots.
795 This Documentation is maintained at:
797   * http://www.pipapo.org/pipawiki/NoBug/Documentation
799 NoBug/Documentation (last edited 2007-03-26 14:51:39 by ct)