X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcfg%2Fdebug.h;h=ef6717c545fcf0c4a51c5d9ea4de7382c45d14b5;hb=39e200e1f43474a96888f97e2271728c9605ccbe;hp=64dc8e4241f67c051d529c7f8f41e74626d73fed;hpb=1ecc7fdbb47d9bee8a66637d978408f4738224f4;p=bertos.git diff --git a/bertos/cfg/debug.h b/bertos/cfg/debug.h index 64dc8e42..ef6717c5 100644 --- a/bertos/cfg/debug.h +++ b/bertos/cfg/debug.h @@ -30,15 +30,24 @@ * * --> * + * \defgroup debug Debugging facilities and macros + * \ingroup core + * \{ + * * \brief Simple debug facilities for hosted and embedded C/C++ applications. * * Debug output goes to stderr in hosted applications. * Freestanding (AKA embedded) applications use \c drv/kdebug.c to output * diagnostic messages to a serial terminal or a JTAG debugger. * - * \version $Id$ - * \author Bernardo Innocenti - */ + * \author Bernie Innocenti + * + * $WIZ$ module_name = "debug" + * $WIZ$ module_configuration = "bertos/cfg/cfg_debug.h" + * $WIZ$ DEBUG = 1 + * $WIZ$ module_depends = "formatwr" + * $WIZ$ module_supports = "not atmega103" + */ #ifndef BERTOS_DEBUG_H #define BERTOS_DEBUG_H @@ -46,79 +55,83 @@ #include #include +#include "cfg/cfg_debug.h" /* CONFIG_KDEBUG_* */ + /* * Defaults for rarely used config stuff. */ -#ifndef CONFIG_KDEBUG_DISABLE_TRACE -#define CONFIG_KDEBUG_DISABLE_TRACE 0 +#ifndef CONFIG_KDEBUG_TRACE +#define CONFIG_KDEBUG_TRACE 1 #endif -#ifndef CONFIG_KDEBUG_ASSERT_NO_TEXT -#define CONFIG_KDEBUG_ASSERT_NO_TEXT 0 +#ifndef CONFIG_KDEBUG_VERBOSE_ASSERT +#define CONFIG_KDEBUG_VERBOSE_ASSERT 1 +#endif + +#ifndef CONFIG_KDEBUG_WALLS +#define CONFIG_KDEBUG_WALLS 1 #endif #if defined(__doxygen__) - /** - * 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. - */ - #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. + */ + #define _DEBUG 1 #endif #ifdef _DEBUG + // STLport specific: enable extra checks + #define __STL_DEBUG 1 - // STLport specific: enable extra checks - #define __STL_DEBUG 1 - - // MSVC specific: Enable memory allocation debug - #if defined(_MSC_VER) - #include - #endif + // MSVC specific: Enable memory allocation debug + #if defined(_MSC_VER) + #include + #endif - /* - * On UNIX systems the extabilished practice is to define - * NDEBUG for release builds and nothing for debug builds. - */ - #ifdef NDEBUG - #undef NDEBUG - #endif + /* + * On UNIX systems the extabilished practice is to define + * NDEBUG for release builds and nothing for debug builds. + */ + #ifdef NDEBUG + #undef NDEBUG + #endif - /** - * This macro duplicates the old MSVC trick of redefining - * THIS_FILE locally to avoid the overhead of many duplicate - * strings in ASSERT(). - */ - #ifndef THIS_FILE - #define THIS_FILE __FILE__ - #endif + /** + * This macro duplicates the old MSVC trick of redefining + * THIS_FILE locally to avoid the overhead of many duplicate + * strings in ASSERT(). + */ + #ifndef THIS_FILE + #define THIS_FILE __FILE__ + #endif - /** - * This macro can be used to conditionally exclude one or more - * statements conditioned on \c _DEBUG, avoiding the clutter - * of ifdef/endif pairs. - * - * \code - * struct FooBar - * { - * int foo; - * bool bar; - * DB(int ref_count;) // Track number of users - * - * void release() - * { - * DB(--ref_count;) - * } - * }; - * \endcode - */ - #define DB(x) x + /** + * This macro can be used to conditionally exclude one or more + * statements conditioned on \c _DEBUG, avoiding the clutter + * of ifdef/endif pairs. + * + * \code + * struct FooBar + * { + * int foo; + * bool bar; + * DB(int ref_count;) // Track number of users + * + * void release() + * { + * DB(--ref_count;) + * } + * }; + * \endcode + */ + #define DB(x) x - #include "cfg/cfg_debug.h" /* CONFIG_KDEBUG_ASSERT_NO_TEXT */ #include /* CPU_HARVARD */ /* These are implemented in drv/kdebug.c */ @@ -129,17 +142,17 @@ void __init_wall(long *wall, int size); #if CPU_HARVARD - #include + #include void kputs_P(const char *PROGMEM str); void kprintf_P(const char *PROGMEM fmt, ...) FORMAT(__printf__, 1, 2); - int __assert_P(const char *PROGMEM cond, const char *PROGMEM file, int line); + int __bassert_P(const char *PROGMEM cond, const char *PROGMEM file, int line); void __trace_P(const char *func); void __tracemsg_P(const char *func, const char *PROGMEM fmt, ...); int __invalid_ptr_P(void *p, const char *PROGMEM name, const char *PROGMEM file, int line); int __check_wall_P(long *wall, int size, const char * PGM_ATTR name, const char * PGM_ATTR file, int line); #define kputs(str) kputs_P(PSTR(str)) #define kprintf(fmt, ...) kprintf_P(PSTR(fmt) ,## __VA_ARGS__) - #define __assert(cond, file, line) __assert_P(PSTR(cond), PSTR(file), (line)) + #define __bassert(cond, file, line) __bassert_P(PSTR(cond), PSTR(file), (line)) #define __trace(func) __trace_P(func) #define __tracemsg(func, fmt, ...) __tracemsg_P(func, PSTR(fmt), ## __VA_ARGS__) #define __invalid_ptr(p, name, file, line) __invalid_ptr_P((p), PSTR(name), PSTR(file), (line)) @@ -147,38 +160,54 @@ #else /* !CPU_HARVARD */ void kputs(const char *str); void kprintf(const char *fmt, ...) FORMAT(__printf__, 1, 2); - int __assert(const char *cond, const char *file, int line); + int __bassert(const char *cond, const char *file, int line); void __trace(const char *func); void __tracemsg(const char *func, const char *fmt, ...) FORMAT(__printf__, 2, 3); int __invalid_ptr(void *p, const char *name, const char *file, int line); int __check_wall(long *wall, int size, const char *name, const char *file, int line); #endif /* !CPU_HARVARD */ - #if !CONFIG_KDEBUG_ASSERT_NO_TEXT - #define ASSERT(x) ((void)(LIKELY(x) ? 0 : __assert(#x, THIS_FILE, __LINE__))) - #define ASSERT2(x, help) ((void)(LIKELY(x) ? 0 : __assert(help " (" #x ")", THIS_FILE, __LINE__))) + #if CONFIG_KDEBUG_VERBOSE_ASSERT + /** + * Assert a pre-condition on code. + */ + #define ASSERT(x) ((void)(LIKELY(x) ? 0 : __bassert(#x, THIS_FILE, __LINE__))) + /** + * Assert a pre-condition and give explanation message when assert fails + */ + #define ASSERT2(x, help) ((void)(LIKELY(x) ? 0 : __bassert(help " (" #x ")", THIS_FILE, __LINE__))) #else - #define ASSERT(x) ((void)(LIKELY(x) ? 0 : __assert("", THIS_FILE, __LINE__))) + #define ASSERT(x) ((void)(LIKELY(x) ? 0 : __bassert("", THIS_FILE, __LINE__))) #define ASSERT2(x, help) ((void)ASSERT(x)) #endif + #define IS_VALID_PTR(p) (LIKELY((void *)(p) >= (void *)CPU_RAM_START)) /** * 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 ASSERT_VALID_PTR_OR_NULL() */ - #define ASSERT_VALID_PTR(p) ((void)(LIKELY((p) >= 0x200) ? 0 : __invalid_ptr(p, #p, THIS_FILE, __LINE__))) + #define ASSERT_VALID_PTR(p) (IS_VALID_PTR(p) \ + ? 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 ASSERT_VALID_PTR() */ - #define ASSERT_VALID_PTR_OR_NULL(p) ((void)(LIKELY((p == NULL) || ((p) >= 0x200)) ? 0 : __invalid_ptr((p), #p, THIS_FILE, __LINE__))) + #define ASSERT_VALID_PTR_OR_NULL(p) ((void)(LIKELY((p == NULL) \ + || ((void *)(p) >= (void *)CPU_RAM_START)) \ + ? 0 : __invalid_ptr((p), #p, THIS_FILE, __LINE__))) - #if !CONFIG_KDEBUG_DISABLE_TRACE + #if CONFIG_KDEBUG_TRACE #define TRACE __trace(__func__) #define TRACEMSG(msg,...) __tracemsg(__func__, msg, ## __VA_ARGS__) #else @@ -186,18 +215,6 @@ #define TRACEMSG(...) do {} while(0) #endif - /** - * \name 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__) - /*\}*/ - /** * Check that the given pointer actually points to an object * of the specified type. @@ -268,6 +285,7 @@ #define ASSERT(x) ((void)0) #endif /* ASSERT */ #define ASSERT2(x, help) ((void)0) + #define IS_VALID_PTR(p) (1) #define ASSERT_VALID_PTR(p) ((void)0) #define ASSERT_VALID_PTR_OR_NULL(p) ((void)0) #define ASSERT_VALID_OBJ(_t, _o) ((void)0) @@ -281,11 +299,6 @@ } #endif - #define DECLARE_WALL(name, size) /* nothing */ - #define FWD_DECLARE_WALL(name, size) /* nothing */ - #define INIT_WALL(name) do {} while (0) - #define CHECK_WALL(name) do {} while (0) - #define NEW_INSTANCE(CLASS) do {} while (0) #define DELETE_INSTANCE(CLASS) do {} while (0) #define ASSERT_ZERO_INSTANCES(CLASS) do {} while (0) @@ -304,9 +317,30 @@ #define kprintf(fmt,...) do { (void)(fmt); } while(0) #else /* ...but GCC can. */ - INLINE void kprintf(UNUSED_ARG(const char *, fmt), ...) { /* nop */ } + INLINE void kprintf(UNUSED_ARG(const char *, fmt), ...) { /* nop */ } #endif #endif /* _DEBUG */ +#if CONFIG_KDEBUG_WALLS + /** + * \name 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__) + /*\}*/ +#else + #define DECLARE_WALL(name, size) /* nothing */ + #define FWD_DECLARE_WALL(name, size) /* nothing */ + #define INIT_WALL(name) do {} while (0) + #define CHECK_WALL(name) do {} while (0) +#endif + +/** \} */ // defgroup debug + #endif /* BERTOS_DEBUG_H */