From 8888c7002deaaaa5a476907ca16ab4a630a95440 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Sat, 23 Jan 2010 05:53:19 +0100 Subject: [PATCH] Documentation update for new 'context' facility. Bump version to 201001.2 --- configure.ac | 2 +- doc/bestpractices.txt | 4 +- doc/dumping.txt | 2 +- doc/macros.txt | 39 ++++++++++------ doc/multithreading.txt | 1 - doc/nobug_manual.conf | 2 + doc/parametertable.txt | 4 +- src/nobug.h | 123 ++++++++++++++++++++++++++++++++----------------- 8 files changed, 112 insertions(+), 65 deletions(-) diff --git a/configure.ac b/configure.ac index 3e91907..d8b2071 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([nobug], [201001.1]) +AC_INIT([nobug], [201001.2]) AC_CONFIG_SRCDIR([src/nobug.h]) AC_CONFIG_AUX_DIR([scripts]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/bestpractices.txt b/doc/bestpractices.txt index cdbc655..3e8c838 100644 --- a/doc/bestpractices.txt +++ b/doc/bestpractices.txt @@ -29,7 +29,7 @@ PARA What and when to check;; PARA Tips & Tricks;; - * TRACE(flagname) or TRACE_DBG(flagname) at the begin of every nontrivial - function will easily log the progress of your application. + * TRACE(flagname) at the begin of every nontrivial function will easily log + the progress of your application. * Trying a RELEASE build will abort on certain conditions (known BUG, TODO's, UNCHECKED code), you can use this to find these spots. diff --git a/doc/dumping.txt b/doc/dumping.txt index 35837a6..0b755ef 100644 --- a/doc/dumping.txt +++ b/doc/dumping.txt @@ -1,6 +1,6 @@ HEAD- Dumping Datastructures;dumping; -How to write DUMP handlers +TODO How to write DUMP handlers One can write functions for dumping complex datastructures using the NoBug facilities. This is done by writing a custom function for each diff --git a/doc/macros.txt b/doc/macros.txt index f43d392..bb3b603 100644 --- a/doc/macros.txt +++ b/doc/macros.txt @@ -2,21 +2,17 @@ HEAD- Macros;; The NoBug interface is almost completely implemented using preprocessor macros. This is required because NoBug uses the -`+++__FILE__+++` and `+++__LINE__+++` macros to log information on the -current file and the current line number within that file. Moreover, -all the flat namespace uppercase identifiers make it ease to recognise -the macros in source code. +`+++__FILE__+++`, `+++__LINE__+++` and `+++__func__+++` macros to +log information on the current file, line number and function. +Moreover, all the flat namespace uppercase identifiers make it ease +to recognise the macros in source code. All macros are available without condition with a `NOBUG_...` prefix. -Macros are also available without this prefix as a convenience, -however macros without this prefix must not have been previously -defined. When `NOBUG_DISABLE_SHORTNAMES` is defined before including -'nobug.h', then only the `NOBUG_` prefixed macros are available and -the short forms will never be defined. - -All assertion and logging macros have a corresponding form -postfixed by `..._DBG`. Such macros will only be active within a -debugger. +Many macros (the common cases) are also available without this prefix +as a convenience, however macros without this prefix must not have +been previously defined. When `NOBUG_DISABLE_SHORTNAMES` is defined +before including 'nobug.h', then only the `NOBUG_` prefixed macros +are available and the short forms will never be defined. A set of macros are provided by NoBug that are postfixed by `..._IF`. These macros have the following form: @@ -29,6 +25,19 @@ They perform the desired action only if `when` is true. For example: The assertion will only be performed if `foo` is non `NULL`. -Debugger versions are available using `..._IF_DBG` postfixed to the name -of the macro. +NoBug also also contains a facility to pass the source context (file, +line, function) around, this can be used to write functions which +handle things where one is more interested in the context of the caller +than the location where the macros appears. + +This macros are postfixed with `..._CTX` and take an extra context +parameter (usually at last but before the logging format specifier and +any variable argument list). The context parameter must be of type +`const struct nobug_context`. + +When the `_CTX` context form is used together with the conditional `_IF` +form then the suffix of the macros is always `..._IF_CTX`. + +The macros which take a context have no short form and must always be +prefixed with `NOBUG_...`. diff --git a/doc/multithreading.txt b/doc/multithreading.txt index f7d03db..54ca618 100644 --- a/doc/multithreading.txt +++ b/doc/multithreading.txt @@ -40,4 +40,3 @@ single global variable. Nobug initializes this variable to `NULL` and then touches it never again. - diff --git a/doc/nobug_manual.conf b/doc/nobug_manual.conf index 2966168..4af1a8d 100644 --- a/doc/nobug_manual.conf +++ b/doc/nobug_manual.conf @@ -23,6 +23,8 @@ //=parametertable +//=srccontext + //=assertions //=logmacros diff --git a/doc/parametertable.txt b/doc/parametertable.txt index 7e15ef3..4f220d5 100644 --- a/doc/parametertable.txt +++ b/doc/parametertable.txt @@ -7,12 +7,12 @@ orthogonal through all macro definitions. `---------`------------------------------------------------------------------ `when` Assertion is only performed if expression `when` is true at runtime `expr` Test without side effects -`fmt` printf-like format string -`...` If not preceded by `fmt`, then printf-like format string followed by its arguments; otherwise, only its arguments `flag` Flag to enable custom logging groups `type` Data type to be checked as a single identifier name `pointer` Pointer to type `lvl` Log level `depth` Depth for invariants and dumps +`context` Source context of type `struct nobug_context` +`...` printf-like format string followed by its arguments --------------------------------------------------------------------------- diff --git a/src/nobug.h b/src/nobug.h index 4930bca..64c31bb 100644 --- a/src/nobug.h +++ b/src/nobug.h @@ -119,9 +119,9 @@ /* //assertions PARA REQUIRE; REQUIRE; preconditions (input parameters) //assertions REQUIRE(expr, ...) -//assertions REQUIRE_CTX(expr, context,...) //assertions REQUIRE_IF(when, expr, ...) -//assertions REQUIRE_IF_CTX(when, expr, context, ...) +//assertions NOBUG_REQUIRE_CTX(expr, context,...) +//assertions NOBUG_REQUIRE_IF_CTX(when, expr, context, ...) //assertions //assertions Precondition (input) check. Use these macros to validate input a //assertions function receives. The checks are enabled in *ALPHA* and *BETA* builds and @@ -147,9 +147,9 @@ /* //assertions PARA ENSURE; ENSURE; postconditions (computation outcomes) //assertions ENSURE(expr, ...) -//assertions ENSURE_CTX(expr, context, ...) //assertions ENSURE_IF(when, expr, ...) -//assertions ENSURE_IF_CTX(when, expr, context, ...) +//assertions NOBUG_ENSURE_CTX(expr, context, ...) +//assertions NOBUG_ENSURE_IF_CTX(when, expr, context, ...) //assertions //assertions Postcondition (progress/output) check. Use these macros to validate the //assertions data a function produces (example: return value). `ENSURE` is enabled @@ -186,9 +186,9 @@ /* //assertions PARA ASSERT; ASSERT; generic assertion //assertions ASSERT(expr, ...) -//assertions ASSERT_CTX(expr, context, ...) //assertions ASSERT_IF(when, expr, ...) -//assertions ASSERT_IF_CTX(when, expr, context, ...) +//assertions NOBUG_ASSERT_CTX(expr, context, ...) +//assertions NOBUG_ASSERT_IF_CTX(when, expr, context, ...) //assertions //assertions Generic check. Use these macros when you want to validate something //assertions which doesn't fall into one of the above categories. A example is when @@ -263,6 +263,7 @@ //assertions //assertions TODO: describe how to create invariant checks //assertions +// 'invariant_context' must be passed in */ #define NOBUG_INVARIANT(type, pointer, depth) \ NOBUG_IF_ALPHA( \ @@ -306,7 +307,8 @@ //dumpmacros DUMP_IF(when, flag, type, pointer, depth) //dumpmacros //dumpmacros This macros call a datastructure dump of the object (`pointer`) in question. -//dumpmacros `DUMP_IF` is the only enabled dumping macro for the RELEASE build level. +//dumpmacros `DUMP` is only available in *ALPHA* and *BETA* builds, `DUMP_IF` is also +//dumpmacros enabled for the RELEASE builds. //dumpmacros */ #define NOBUG_DUMP(flag, type, pointer, depth) \ @@ -324,17 +326,17 @@ /* //dumpmacros PARA DUMP_LOG; DUMP_LOG; logging helper for dumping -//dumpmacros DUMP_LOG(fmt, ...) -//dumpmacros DUMP_LOG_IF(when, fmt, ...) +//dumpmacros DUMP_LOG(...) +//dumpmacros DUMP_LOG_IF(when, ...) //dumpmacros //dumpmacros Any output from `DUMP` handlers should be done by these macros. //dumpmacros //dumpmacros Dumping is by default done on level `LOG_DEBUG`, this can be overridden by //dumpmacros defining `NOBUG_DUMP_LEVEL` to some other level. //dumpmacros +// TODO document: 'dump_context' must be passed in */ - #define NOBUG_DUMP_LOG(...) \ NOBUG_LOG_( &nobug_flag_NOBUG_ON, NOBUG_DUMP_LEVEL, \ "DUMP", dump_context, \ @@ -356,6 +358,10 @@ /* //logmacros HEAD- Logging Macros;; //logmacros +//logmacros Logging targets a flag (except for `ECHO`) and is done at a log-level relating to syslog levels. +//logmacros +//logmacros NOTE: there is no logging macro for `LOG_EMERG`, this is only used by the assertions as fatal message +//logmacros //logmacros PARA ECHO; ECHO; unconditional logging for tests //logmacros ECHO(...) //logmacros @@ -370,6 +376,8 @@ //logmacros PARA ALERT; ALERT; about to die //logmacros ALERT(flag, ...) //logmacros ALERT_IF(when, flag, ...) +//logmacros NOBUG_ALERT_CTX(flag, context, ...) +//logmacros NOBUG_ALERT_IF_CTX(when, flag, context, ...) //logmacros //logmacros This is the most critical condition an application might log. This might be used //logmacros if an error occurs which can not be handled except a safe shutdown for example. @@ -394,6 +402,8 @@ //logmacros PARA CRITICAL; CRITICAL; can not continue //logmacros CRITICAL(flag, ...) //logmacros CRITICAL_IF(when, flag, ...) +//logmacros NOBUG_CRITICAL_CTX(flag, context, ...) +//logmacros NOBUG_CRITICAL_IF_CTX(when, flag, context, ...) //logmacros //logmacros An error which can not be handled occured but the application does not need to be //logmacros shutdowen, perhaps waiting for an operator to fix the cause. @@ -415,8 +425,10 @@ /* //logmacros PARA ERROR; ERROR; something gone wrong -//logmacros ERROR(flag, fmt, ...) -//logmacros ERROR_IF(when, flag, fmt, ...) +//logmacros ERROR(flag, ...) +//logmacros ERROR_IF(when, flag, ...) +//logmacros NOBUG_ERROR_CTX(flag, context, ...) +//logmacros NOBUG_ERROR_IF_CTX(when, flag, context, ...) //logmacros //logmacros Application takes a error handling brach //logmacros @@ -437,8 +449,10 @@ /* //logmacros PARA WARN; WARN; unexpected fixable error -//logmacros WARN(flag, fmt, ...) -//logmacros WARN_IF(when, flag, fmt, ...) +//logmacros WARN(flag, ...) +//logmacros WARN_IF(when, flag, ...) +//logmacros NOBUG_WARN_CTX(flag, context, ...) +//logmacros NOBUG_WARN_IF_CTX(when, flag, context, ...) //logmacros //logmacros Rare, handled but unexpected branch //logmacros @@ -459,8 +473,10 @@ /* //logmacros PARA INFO; INFO; progress message -//logmacros INFO(flag, fmt, ...) -//logmacros INFO_IF(when, flag, fmt, ...) +//logmacros INFO(flag, ...) +//logmacros INFO_IF(when, flag, ...) +//logmacros NOBUG_INFO_CTX(flag, context, ...) +//logmacros NOBUG_INFO_IF_CTX(when, flag, context, ...) //logmacros //logmacros Message about program progress //logmacros @@ -481,8 +497,10 @@ /* //logmacros PARA NOTICE; NOTICE; detailed progress message -//logmacros NOTICE(flag, fmt, ...) -//logmacros NOTICE_IF(when, flag, fmt, ...) +//logmacros NOTICE(flag, ...) +//logmacros NOTICE_IF(when, flag, ...) +//logmacros NOBUG_NOTICE_CTX(flag, context, ...) +//logmacros NOBUG_NOTICE_IF_CTX(when, flag, context, ...) //logmacros //logmacros More detailed progress message //logmacros @@ -502,8 +520,10 @@ /* //logmacros PARA TRACE; TRACE; debugging level message -//logmacros TRACE(flag, fmt, ...) -//logmacros TRACE_IF(when, flag, fmt, ...) +//logmacros TRACE(flag, ...) +//logmacros TRACE_IF(when, flag, ...) +//logmacros NOBUG_TRACE_CTX(flag, context, ...) +//logmacros NOBUG_TRACE_IF_CTX(when, flag, context, ...) //logmacros //logmacros Very fine grained messages //logmacros @@ -526,10 +546,8 @@ /* //logmacros PARA LOG; LOG; generic logging -//logmacros LOG(flag, lvl, ...) -//logmacros LOG_CTX(flag, lvl, context, ...) -//logmacros LOG_IF(when, flag, lvl, ...) -//logmacros LOG_IF_CTX(when, flag, lvl, context, ...) +//logmacros NOBUG_LOG_CTX(flag, lvl, context, ...) +//logmacros NOBUG_LOG_IF_CTX(when, flag, lvl, context, ...) //logmacros //logmacros Generic logging macro which takes the level explicitly, //logmacros avoid this, unless you implement your own logging facilities. @@ -548,10 +566,9 @@ /* low level logging handler - Note: all fmt concatenations us a empty string ""__VA_ARG__ + Note: all fmt concatenations use an empty string ""__VA_ARG__ except this one which must use a single space " " before __VA_ARGS__ for formatting the log message correctly (and silence a gcc warning) */ - #define NOBUG_LOG_(flag, lvl, what, context, ...) \ NOBUG_WHEN (lvl <= NOBUG_LOG_BASELIMIT && lvl <= (flag)->limits[NOBUG_TARGET_RINGBUFFER], \ nobug_log (flag, lvl, what, context, " "__VA_ARGS__) \ @@ -584,8 +601,6 @@ //logmacros This macros can be defined before including 'nobug.h' to some other //logmacros log level (as defined in 'syslog.h'). //logmacros -//logmacros NOTE: there is no logging macro for `LOG_EMERG` since this is used by the assertions as fatal message -//logmacros */ #ifndef NOBUG_LOG_BASELIMIT_ALPHA #define NOBUG_LOG_BASELIMIT_ALPHA LOG_DEBUG @@ -607,7 +622,15 @@ #endif /* -//srccontext HEAD- Source Contexts;; +//srccontext HEAD~ Source Contexts; NOBUG_CONTEXT; pass information about the source location +//srccontext NOBUG_CONTEXT +//srccontext NOBUG_CONTEXT_NOFUNC +//srccontext +//srccontext NoBug passes information about the source location of a given statement in +//srccontext `const struct nobug_context` structures. These can be generated with +//srccontext `NOBUG_CONTEXT` or `NOBUG_CONTEXT_NOFUNC`. The later one doesn't define a +//srccontext function name and must be used when the function context is not available +//srccontext like in static initialization etc.. //srccontext */ @@ -727,6 +750,7 @@ NOTREACHED abort abort nothing NOBUG_ABORT; \ } while (0)) + /* //annotations PARA ELSE_NOTREACHED; ELSE_NOTREACHED; alternative never taken //annotations ELSE_NOTREACHED(...) @@ -742,7 +766,6 @@ NOTREACHED abort abort nothing } while (0)) - /* //faultinjection HEAD- Fault injection;; //faultinjection @@ -1016,11 +1039,13 @@ NOTREACHED abort abort nothing /* //resourcemacros PARA RESOURCE_ANNOUNCE; RESOURCE_ANNOUNCE; publish new resources //resourcemacros RESOURCE_ANNOUNCE(flag, type, name, identifier, handle) +//resourcemacros NOBUG_RESOURCE_ANNOUNCE_RAW(flagptr, type, name, ptr, handle) +//resourcemacros NOBUG_RESOURCE_ANNOUNCE_RAW_CTX(flagptr, type, name, ptr, handle, context) //resourcemacros //resourcemacros Publishes resources. //resourcemacros //resourcemacros `flag`:: -//resourcemacros the NoBug flag which turns logging on for this macro +//resourcemacros the NoBug flag name which turns logging on for this macro //resourcemacros `type`:: //resourcemacros a string which should denote the domain of the resource, //resourcemacros examples are "file", "mutex", "lock", "database" and so on @@ -1067,6 +1092,8 @@ NOTREACHED abort abort nothing /* //resourcemacros PARA RESOURCE_FORGET; RESOURCE_FORGET; remove resources //resourcemacros RESOURCE_FORGET(flag, handle) +//resourcemacros NOBUG_RESOURCE_FORGET_RAW(flagptr, handle) +//resourcemacros NOBUG_RESOURCE_FORGET_RAW_CTX(flagptr, handle, context) //resourcemacros //resourcemacros Removes resources that have become unavailable from the registry. //resourcemacros @@ -1108,6 +1135,7 @@ NOTREACHED abort abort nothing /* //resourcemacros PARA RESOURCE_ENTER; RESOURCE_ENTER; claim a resource //resourcemacros RESOURCE_ENTER(flag, announced, user, state, handle) +//resourcemacros NOBUG_RESOURCE_ENTER_CTX(flag, resource, user, state, handle, context) //resourcemacros //resourcemacros Acquire a resource. //resourcemacros @@ -1118,13 +1146,12 @@ NOTREACHED abort abort nothing //resourcemacros `user`:: //resourcemacros a free-form identifier //resourcemacros `state`:: -//resourcemacros the initial state, one of `NOBUG_RESOURCE_WAITING`, +//resourcemacros the initial state, one of `NOBUG_RESOURCE_WAITING`, `NOBUG_RESOURCE_TRYING`, //resourcemacros `NOBUG_RESOURCE_EXCLUSIVE`, `NOBUG_RESOURCE_RECURSIVE` or `NOBUG_RESOURCE_SHARED` //resourcemacros `handle`:: //resourcemacros a `NOBUG_RESOURCE_HANDLE` which will be initialized to the //resourcemacros entering node //resourcemacros -//resourcemacros */ #define NOBUG_RESOURCE_ENTER(flag, resource, user, state, handle) \ NOBUG_RESOURCE_ENTER_CTX(flag, resource, user, state, handle, NOBUG_CONTEXT) @@ -1161,6 +1188,7 @@ NOTREACHED abort abort nothing //resourcemacros PARA RESOURCE_WAIT; RESOURCE_WAIT; wait for a resource to become available //resourcemacros RESOURCE_WAIT(flag, resource, user, handle) +//resourcemacros NOBUG_RESOURCE_WAIT_CTX(flag, resource, user, handle, context) //resourcemacros //resourcemacros This is just an alias for RESOURCE_ENTER(flag, resource, user, NOBUG_RESOURCE_WAITING, handle) //resourcemacros @@ -1183,6 +1211,7 @@ NOTREACHED abort abort nothing //resourcemacros PARA RESOURCE_TRY; RESOURCE_TRY; wait for a resource to become available //resourcemacros RESOURCE_TRY(flag, resource, user, handle) +//resourcemacros NOBUG_RESOURCE_TRY_CTX(flag, resource, user, handle, context) //resourcemacros //resourcemacros This is just an alias for RESOURCE_ENTER(flag, resource, user, NOBUG_RESOURCE_TRYING, handle). //resourcemacros Trying on a resource is similar to waiting but will not trigger a deadlock check. This can be used @@ -1198,6 +1227,9 @@ NOTREACHED abort abort nothing /* //resourcemacros PARA RESOURCE_STATE; RESOURCE_STATE; change the state of a resource //resourcemacros RESOURCE_STATE(flag, entered, state) +//resourcemacros NOBUG_RESOURCE_STATE_CTX(flag, state, entered, context) +//resourcemacros NOBUG_RESOURCE_STATE_RAW(flagptr, state, entered) +//resourcemacros NOBUG_RESOURCE_STATE_RAW_CTX(flagptr, nstate, entered, context) //resourcemacros //resourcemacros Changes resource's state. //resourcemacros @@ -1252,7 +1284,9 @@ NOTREACHED abort abort nothing /* //resourcemacros PARA RESOURCE_LEAVE; RESOURCE_LEAVE; relinquish a claimed resource -//resourcemacros RESOURCE_LEAVE(flag, handle) +//resourcemacros RESOURCE_LEAVE(flag, handle){} +//resourcemacros NOBUG_RESOURCE_LEAVE_RAW(flagptr, handle){} +//resourcemacros NOBUG_RESOURCE_LEAVE_RAW_CTX(flagptr, handle, context){} //resourcemacros //resourcemacros Disconnect from a resource identified with its handle. //resourcemacros @@ -1319,6 +1353,8 @@ NOTREACHED abort abort nothing //resourcemacros PARA RESOURCE_ASSERT_STATE; RESOURCE_ASSERT_STATE; assert the state of a resource //resourcemacros RESOURCE_ASSERT_STATE(resource, state) //resourcemacros RESOURCE_ASSERT_STATE_IF(when, resource, state) +//resourcemacros NOBUG_RESOURCE_ASSERT_STATE_CTX(resource, state, context) +//resourcemacros NOBUG_RESOURCE_ASSERT_STATE_IF_CTX(when, resource, state, context) //resourcemacros //resourcemacros Assert that we have a resource in a given state. For multithreaded programms the topmost //resourcemacros state of the calling thread is checked, for non threadeded programs the most recent state on @@ -1524,7 +1560,7 @@ NOBUG_IFNOT(NOBUG_USE_VALGRIND, 0) /* //toolmacros PARA Backtraces; BACKTRACE; generate a backtrace //toolmacros BACKTRACE -//toolmacros BACKTRACE_CTX(context) +//toolmacros NOBUG_BACKTRACE_CTX(context) //toolmacros //toolmacros The backtrace macro logs a stacktrace using the NoBug facilities. //toolmacros This is automatically called when NoBug finds an error and is due @@ -1582,6 +1618,10 @@ NOBUG_IF(NOBUG_USE_VALGRIND, \ //toolmacros If not overridden, evaluates to `NOBUG_ABORT_`. One can override this before including //toolmacros `nobug.h` to customize abortion behaviour. This will be local to the translation unit then. //toolmacros +#ifndef NOBUG_ABORT +#define NOBUG_ABORT NOBUG_ABORT_ +#endif + #define NOBUG_ABORT_ \ do { \ nobug_ringbuffer_allsync (); \ @@ -1590,9 +1630,6 @@ NOBUG_IF(NOBUG_USE_VALGRIND, \ abort(); \ } while(0) -#ifndef NOBUG_ABORT -#define NOBUG_ABORT NOBUG_ABORT_ -#endif /* init and other function wrapers @@ -1997,16 +2034,16 @@ struct nobug_ringbuffer enum nobug_ringbuffer_flags { - NOBUG_RINGBUFFER_DEFAULT, /* Default is to overwrite file and delete it on nobug_ringbuffer_destroy */ - NOBUG_RINGBUFFER_APPEND = 1, /* use existing backing file, append if possible */ - NOBUG_RINGBUFFER_TEMP = 2, /* unlink file instantly */ - NOBUG_RINGBUFFER_KEEP = 4 /* dont unlink the file at destroy */ + NOBUG_RINGBUFFER_DEFAULT, /* Default is to overwrite file and delete it on nobug_ringbuffer_destroy */ + NOBUG_RINGBUFFER_APPEND = 1, /* use existing backing file, append if possible */ + NOBUG_RINGBUFFER_TEMP = 2, /* unlink file instantly */ + NOBUG_RINGBUFFER_KEEP = 4 /* dont unlink the file at destroy */ }; - /* Note: some flags conflict (TEMP with KEEP) nobug_ringbuffer will not error on these but continue gracefully with sane (but undefined) semantics. */ + struct nobug_ringbuffer* nobug_ringbuffer_init (struct nobug_ringbuffer* self, size_t size, const char * name, int flags); -- 2.11.4.GIT