diff --git a/Kconfig b/Kconfig index 0ce1787a86307162b2425dac359c19a6c988800e..8735d494abf09b4fa7a3bba5db1d23e911a6c82e 100644 --- a/Kconfig +++ b/Kconfig @@ -21,6 +21,15 @@ config PRINT_BUFSIZE int default 128 +config ASSERT + bool "Build assertion checks in the code" + default y + help + Build assertions in the code, to catch unexpected situations. + When an assertion fails the code loops over repeating the + error message every second. OTOH, panic() is always built, + with no Kconfig -- and it does the same, unconditionally. + config RAMSIZE int default 65536 if WR_SWITCH diff --git a/include/assert.h b/include/assert.h new file mode 100644 index 0000000000000000000000000000000000000000..c4aa7f16158ad59b8d3e9cc9e7af654f23db05a7 --- /dev/null +++ b/include/assert.h @@ -0,0 +1,33 @@ +#ifndef __ASSERT_H__ +#define __ASSERT_H__ + +/* + * Both panic and assert loop over the console, re-printing the + * message, so you can connnect to a paniced node and see the message + * that caused the panic. assert_warn(condition) is once only, like + * warn_on(!condition) in the kernel. + */ + +extern void panic(const char *fmt, ...) + __attribute__((format(printf,1,2))); + +#define assert(cond, fmt, ...) \ + if (CONFIG_HAS_ASSERT && !(cond)) \ + __assert(__func__, __LINE__, 1 /* forever */, fmt __VA_ARGS__) + +#define assert_warn(cond, fmt, ...) \ + if (CONFIG_HAS_ASSERT && !(cond)) \ + __assert(__func__, __LINE__, 0 /* once */, fmt __VA_ARGS__) + + +extern void __assert(const char *func, int line, int forever, + const char *fmt, ...) + __attribute__((format(printf, 4, 5))); + +#ifdef CONFIG_ASSERT +# define CONFIG_HAS_ASSERT 1 +#else +# define CONFIG_HAS_ASSERT 0 +#endif + +#endif /* __ASSERT_H__ */ diff --git a/lib/assert.c b/lib/assert.c new file mode 100644 index 0000000000000000000000000000000000000000..eef81bc486bc2cd868a1bd8431cd29cc314e5e12 --- /dev/null +++ b/lib/assert.c @@ -0,0 +1,37 @@ +#include <stdarg.h> +#include <assert.h> +#include <wrc.h> + +void panic(const char *fmt, ...) +{ + va_list args; + + while (1) { + pp_printf("Panic: "); + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + usleep(1000 * 1000); + } +} + +void __assert(const char *func, int line, int forever, + const char *fmt, ...) +{ + va_list args; + + while (1) { + pp_printf("Assertion failed (%s:%i)", func, line); + if (fmt && fmt[0]) { + pp_printf(": "); + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + } else { + pp_printf(".\n"); + } + if (!forever) + break; + usleep(1000 * 1000); + } +} diff --git a/lib/lib.mk b/lib/lib.mk index 9d797e9a5877c1c9b1dbe359b5eb9d51529146d6..9034edea91e32d3289f3e480efb9c6fddd884530 100644 --- a/lib/lib.mk +++ b/lib/lib.mk @@ -1,4 +1,5 @@ obj-y += lib/util.o +obj-y += lib/assert.o obj-$(CONFIG_LM32) += \ lib/atoi.o \