AXL_DEBUG_ASSERT — debug-build invariant guards

AXL_DEBUG_ASSERT(expr) enforces an internal invariant — a condition the code’s own logic guarantees, which a future edit could quietly break. It is distinct from a runtime error check, which validates input and returns an AxlStatus; an assert documents and enforces an internal contract and is compiled out under NDEBUG, so release builds pay nothing.

Its purpose is to catch a concurrency or lifecycle fault at its cause, in a debug or test build, instead of as a downstream symptom (a wedge, a stream desync, a corrupted dispatch) that only a consumer’s integration surfaces later. See docs/AXL-Concurrency.md § “Testing the model” for how this fits the broader strategy of modeling the consumer topology in-repo.

On failure (debug/test builds only) it emits a loud, grep-able log line — AXL_DEBUG_ASSERT FAILED: <file>:<line> <func>(): <expr> — and continues: it does not abort or wedge, so an integration test can observe the marker and still run to its results footer. _axl_debug_assert_count() is a test hook to confirm a guard fired without parsing logs.

API Reference

Defines

AXL_DEBUG_ASSERT(expr)

Assert an internal invariant. No-op under NDEBUG. On failure (debug/ test builds) logs the AXL_DEBUG_ASSERT FAILED: marker and continues.

AXL_DEBUG_ASSERT_MSG(expr, msg)

As AXL_DEBUG_ASSERT, with an extra human-readable context string.

Functions

void _axl_debug_assert_fail(const char *file, int line, const char *func, const char *expr, const char *msg)

Record + log a failed debug assertion (internal; invoked by the AXL_DEBUG_ASSERT macros — do not call directly).

axl-debug.h:

Debug-build invariant assertions.

AXL_DEBUG_ASSERT guards an internal invariant: a condition the code’s own logic guarantees, which a future edit could quietly break. Unlike a runtime error check (which validates input and returns an AxlStatus), a debug assert documents and enforces an internal contract, and it is compiled out under NDEBUG so it costs release builds nothing.

The purpose is to catch a concurrency/lifecycle fault at its cause, in a debug or test build, instead of as a downstream symptom (a wedge, a desync, a corrupted dispatch) that only a consumer’s integration surfaces days later. See docs/AXL-Concurrency.md § “Testing the model”.

Behavior on failure (debug/test builds only): emit a loud, grep-able log line AXL_DEBUG_ASSERT FAILED: <file>:<line> <func>(): <expr> and continue — it does not abort or wedge, so an integration test can observe the marker on the serial log and still run to its results footer. _axl_debug_assert_count() is a test hook for unit tests to confirm a guard fired without parsing logs.

Under NDEBUG (RELEASE builds), the macros expand to ((void)0) and the guarded expression is not evaluated.

Emits the AXL_DEBUG_ASSERT FAILED: marker and increments the process-global failure counter, then returns (never aborts).

Parameters:
  • file – source file (FILE)

  • line – source line (LINE)

  • func – enclosing function (func)

  • expr – the failed expression, stringized

  • msg – optional extra context, or NULL

size_t _axl_debug_assert_count(void)

Number of AXL_DEBUG_ASSERT failures observed this run.

Test hook: a unit test triggers a guard and asserts the count incremented. Always defined (returns 0 under NDEBUG, where the macros never call the failure path).

Returns:

cumulative failure count since process start.