BeRTOS
Defines | Functions
Debugging facilities and macros
BeRTOS core functionality

Simple debug facilities for hosted and embedded C/C++ applications. More...

Defines

#define _DEBUG   1
 Preprocessor symbol defined only for debug builds.
#define THIS_FILE   __FILE__
 This macro duplicates the old MSVC trick of redefining THIS_FILE locally to avoid the overhead of many duplicate strings in ASSERT().
#define DB(x)   x
 This macro can be used to conditionally exclude one or more statements conditioned on _DEBUG, avoiding the clutter of ifdef/endif pairs.
#define ASSERT(x)   ((void)(LIKELY(x) ? 0 : __bassert(#x, THIS_FILE, __LINE__)))
 Assert a pre-condition on code.
#define ASSERT2(x, help)   ((void)(LIKELY(x) ? 0 : __bassert(help " (" #x ")", THIS_FILE, __LINE__)))
 Assert a pre-condition and give explanation message when assert fails.
#define ASSERT_VALID_PTR(p)
 Check that the given pointer is either NULL or pointing to valid memory.
#define ASSERT_VALID_PTR_OR_NULL(p)
 Check that the given pointer is not pointing to invalid memory.
#define ASSERT_VALID_OBJ(_t, _o)
 Check that the given pointer actually points to an object of the specified type.

Functions

int kputnum (int num)
 Cheap function to print small integers without using printf().
void kdump (const void *buf, size_t len)
 Dump binary data in hex.

Debug object creation and destruction.

These macros help track some kinds of leaks in C++ programs.

Usage is as follows:

   class Foo
   {
       DECLARE_INSTANCE_TRACKING(Foo)

       Foo()
       {
           NEW_INSTANCE(Foo);
           // ...
       }

       ~Foo()
       {
           DELETE_INSTANCE(Foo);
           // ...
       }
   };

   // Put this in the implementation file of the class
   IMPLEMENT_INSTANCE_TRACKING(Foo)

   // Client code
   int main(void)
   {
        Foo *foo = new Foo;
        cout << GET_INSTANCE_COUNT(Foo) << endl; // prints "1"
        delete foo;
        ASSERT_ZERO_INSTANCES(Foo); // OK
   }
#define NEW_INSTANCE(CLASS)   do { ++CLASS::__instances } while (0)
#define DELETE_INSTANCE(CLASS)   do { --CLASS::__instances } while (0)
#define ASSERT_ZERO_INSTANCES(CLASS)   ASSERT(CLASS::__instances == 0)
#define GET_INSTANCE_COUNT(CLASS)   (CLASS::__instances)
#define DECLARE_INSTANCE_TRACKING(CLASS)   static int __instances
#define IMPLEMENT_INSTANCE_TRACKING(CLASS)   int CLASS::__instances = 0

Walls to detect data corruption

#define WALL_SIZE   8
#define WALL_VALUE   (long)0xABADCAFEL
#define DECLARE_WALL(name, size)   long name[(size) / sizeof(long)];
#define FWD_DECLARE_WALL(name, size)   extern long name[(size) / sizeof(long)];
#define INIT_WALL(name)   __init_wall((name), countof(name))
#define CHECK_WALL(name)   __check_wall((name), countof(name), #name, THIS_FILE, __LINE__)

Detailed Description

Simple debug facilities for hosted and embedded C/C++ applications.

Debug output goes to stderr in hosted applications. Freestanding (AKA embedded) applications use drv/kdebug.c to output diagnostic messages to a serial terminal or a JTAG debugger.

Author:
Bernie Innocenti <bernie@codewiz.org>

Define Documentation

#define _DEBUG   1

Preprocessor symbol defined only for debug builds.

The build infrastructure must arrange for _DEBUG to be predefined for all the source files being compiled.

This is compatible with the MSVC convention for the default Debug and Release project targets.

Definition at line 85 of file debug.h.

#define ASSERT_VALID_PTR (   p)
Value:
(IS_VALID_PTR(p) \
        ? 0 : __invalid_ptr(p, #p, THIS_FILE, __LINE__))

Check that the given pointer is either NULL or pointing to valid memory.

The assumption here is that valid pointers never point to low memory regions. This helps catching pointers taken from struct/class memebers when the struct pointer was NULL.

See also:
ASSERT_VALID_PTR_OR_NULL()

Definition at line 194 of file debug.h.

#define ASSERT_VALID_PTR_OR_NULL (   p)
Value:
((void)(LIKELY((p == NULL) \
        || ((void *)(p) >= (void *)CPU_RAM_START)) \
        ? 0 : __invalid_ptr((p), #p, THIS_FILE, __LINE__)))

Check that the given pointer is not pointing to invalid memory.

Note:
The check for invalid memory is architecture specific and conservative. The current implementation only checks against a lower bound.
See also:
ASSERT_VALID_PTR()

Definition at line 206 of file debug.h.

#define DB (   x)    x

This macro can be used to conditionally exclude one or more statements conditioned on _DEBUG, avoiding the clutter of ifdef/endif pairs.

     struct FooBar
     {
         int foo;
         bool bar;
         DB(int ref_count;) // Track number of users

         void release()
         {
             DB(--ref_count;)
         }
     };

Definition at line 133 of file debug.h.