Go to the first, previous, next, last section, table of contents.


DI.h: debugger based invariant checking

This implements the debugger based invariant checking code. The first two macros are the normal user interface; the remainder are used for configuring the behaviour on failure, etc. Note that these macros have no effect unless you run your program under the debugger and read in the commands generated by the `nana' command.

Macro: void DI (bool exprn)
The exprn should always be true if the program is working. If it is true then nothing happens otherwise the code given by `DI_DEFAULT_HANDLER' will be called which by default prints a message and dies just like `assert.h'.

The checking using DI can be enabled and disabled by using the DI_LEVEL and DI_DEFAULT_GUARD macros. See the definitions below for these macros for further details.

Note that exprn should have no side-effects(6) since disabling the checking shouldn't change your programs behaviour.

Macro: void DN (bool exprn)
The opposite of `DI', i.e. the expression must never ever be true if the program is working properly. It is equivelant to I(!(e)) and exists as piece of syntactic sugar which is helpful for complicated boolean expressions.

Macro: int DI_LEVEL
The `DI_LEVEL' macro is used to globally enable and disable checking, in particular it can take on one of three values:

0
Disable all checking. Regardless of anything else no code will be generated for DI, DN, etc.
1
Enable checking only if the corresponding guard condition is true. The guard condition can be used to enable and disable checking at compile and run time.
2
Enable all checking regardless of guard conditions, etc.

DI_LEVEL defaults to 1.

Macro: bool DI_DEFAULT_GUARD
The DI_DEFAULT_GUARD is used to selectively enable or disable checking at compile or run time.

DI_DEFAULT_GUARD defaults to TRUE, i.e. always enabled.

A user would typically define DI_DEFAULT_GUARD to be global or local variable which is used to turn checking on or off at run--time. For example:

#define DI_DEFAULT_GUARD (i_guard)

extern int i_guard;

Macro: text DI_DEFAULT_PARAMS
This is passed off to the DI_DEFAULT_HANDLER and defaults to nothing, it is just some text and is intended to pass failure codes (e.g. IEH303) or requests (e.g. HW_DEAD) information off to the handler.

DI_DEFAULT_PARAMS defaults to nothing.

Macro: void DI_DEFAULT_HANDLER (char *exprn, char *file, int line, param)

When an error is detected the DI_DEFAULT_HANDLER will be called to handle the error. The arguments are:

exprn
A string representation of the expression that has failed, e.g. "I(i>=0)".
file
The file that this error occurred in, i.e. __FILE__.
line
The line number for the error, i.e. __LINE__.
param
An optional parameter which can be passed across which defaults to DI_DEFAULT_PARAMS. This can be used to pass failure codes or other information from the checking code to the handler.

Macro: void DI_MAKE_VALID_BREAKPOINT (exprn e)
This macro is used to ensure that a breakpoint can be set at the location we are checking using DI, etc. It defaults to asm("nop") and can be redefined by the user.

Macro: void DI (bool e)
Macro: void DIG (bool e, bool g)
Macro: void DIH (bool e, Macro h)
Macro: void DIP (bool e, Text p)
Macro: void DIGH (bool e, bool g, Macro h)
Macro: void DIGP (bool e, bool g, Text p)
Macro: void DIHP (bool e, Macro h, Text p)
Macro: void DIGHP (bool e, bool g, Macro h, Text p)
Macro: void DN (bool e)
Macro: void DNG (bool e, bool g)
Macro: void DNH (bool e, Macro h)
Macro: void DNP (bool e, Text p)
Macro: void DNGH (bool e, bool g, Macro h)
Macro: void DNGP (bool e, bool g, Text p)
Macro: void DNHP (bool e, Macro h, Text p)
Macro: void DNGHP (bool e, bool g, Macro h, Text p)

All of these macros are used to individually override the default values defined above. Normally these macros would be used in a system wide header file to define macros appropriate for the application.

Macro: void DS (e)
Macro: void DSG (e, g)
These macros are used to assign values to convenience variables in the debugger. Convenience variables are dynamically typed, global in scope and initialised to 0. They start with a single $ and can be used be used for saving the state of program or for counting events. The `DS' macro executes e under the same rules as DI. The `DSG' macro executes e only if the the expression g is true.

Note that `DS' and `DSG' can also be used for modifying C variables and calling functions.


Go to the first, previous, next, last section, table of contents.