Unified panic and assert system for embedded systems.
C99, zero dependencies, zero allocations, hook-chain architecture, portable.
Embedded projects often end up with fragmented failure handling:
assert(), while(1), ad-hoc reset calls, and missing diagnostics.
microassert provides one panic pipeline:
- Capture context (file, line, function, message, timestamp)
- Execute hooks (log, dump, persist, flush)
- Continue, reset, or halt based on severity
- Four severities:
WARN,ERROR,FATAL,HALT - Hook chain with configurable order
- Panic context capture and formatted messages
- Re-entrancy guard for nested panic scenarios
- Optional panic history ring buffer
- Global singleton plus instance-based API
- Compile-time switches for footprint control
#include "massert.h"
static uint32_t clock_ms(void) { return HAL_GetTick(); }
static void log_hook(const massert_info_t *info, void *ctx) {
(void)ctx;
// route info->msg / info->severity to your logger
}
int main(void) {
massert_t *ma = massert_global();
massert_init(ma, clock_ms);
massert_add_hook(ma, log_hook, NULL);
MASSERT(1 == 1);
MASSERT_WARN(2 == 3, "non-fatal mismatch");
MASSERT_MSG(4 == 5, "fatal mismatch: %d != %d", 4, 5);
return 0;
}From repository root:
clang -std=c99 -Wall -Wextra -Wpedantic -Werror -Iinclude src/massert.c tests/test_all.c -o tests/test_all
./tests/test_allOn Linux with GCC:
gcc -std=c99 -Wall -Wextra -Wpedantic -Werror -Iinclude src/massert.c tests/test_all.c -o tests/test_all
./tests/test_all| Macro | Default | Description |
|---|---|---|
MASSERT_MAX_HOOKS |
4 |
Maximum hooks in chain |
MASSERT_MSG_SIZE |
96 |
Message buffer size |
MASSERT_ENABLE_LOCATION |
1 |
Capture file/line/function |
MASSERT_ENABLE_HISTORY |
1 |
Store panic history |
MASSERT_HISTORY_DEPTH |
4 |
History ring size |
MIT, see LICENSE.