assert.c (1711B)
1 //===-- assert.c - kit freestanding assert failure ----------------------===// 2 // 3 // SPDX-License-Identifier: 0BSD 4 //===----------------------------------------------------------------------===// 5 // 6 // __kit_assert_fail is the freestanding target of a failed assert(). It emits a 7 // human-readable banner and then a raw backtrace, both through the weak 8 // __kit_backtrace_write sink (see rt/include/kit/backtrace.h), before trapping. 9 // When no sink is wired the banner and trace are discarded, so this stays 10 // link-clean and printf-free in a bare freestanding image; a host that wires 11 // the sink (typically write(2) to stderr) gets a diagnosable trap. 12 13 #include <kit/backtrace.h> 14 #include <stddef.h> 15 16 static void bt_emit(const char* s) { 17 size_t n = 0; 18 if (!s) return; 19 while (s[n]) n++; 20 __kit_backtrace_write(s, n); 21 } 22 23 static void bt_emit_int(int v) { 24 char buf[12]; /* "-2147483648" + slack; we pass an explicit length */ 25 int k = (int)sizeof buf; 26 int neg = v < 0; 27 unsigned u = neg ? 0u - (unsigned)v : (unsigned)v; 28 do { 29 buf[--k] = (char)('0' + (int)(u % 10u)); 30 u /= 10u; 31 } while (u && k > 0); 32 if (neg && k > 0) buf[--k] = '-'; 33 __kit_backtrace_write(buf + k, (size_t)((int)sizeof buf - k)); 34 } 35 36 __attribute__((weak)) void __kit_assert_fail(const char* expr, const char* file, 37 int line, const char* func) { 38 bt_emit("kit: assertion failed: "); 39 bt_emit(expr ? expr : "(unknown)"); 40 if (file) { 41 bt_emit(", file "); 42 bt_emit(file); 43 } 44 bt_emit(", line "); 45 bt_emit_int(line); 46 if (func) { 47 bt_emit(", function "); 48 bt_emit(func); 49 } 50 bt_emit("\n"); 51 __kit_print_backtrace(); 52 __builtin_trap(); 53 for (;;) { 54 } 55 }