LogWrite
Description
Direct log message writer. Stateless: no setup, no teardown, no globals. INFO lines go to the normal output channel (fd 1 on POSIX); ERROR and FATAL go to the diagnostic channel (fd 2). FATAL additionally appends a captured stack trace before returning to the caller – the LOG_FATAL macro then calls Abort().
Parameters
| Name | Direction | Description |
|---|---|---|
type |
in | Severity selector. |
tag |
in | Caller identifier; defaulted to “misra” if NULL. The LOG_* macros pass __func__ here. |
line |
in | Source line; the LOG_* macros pass __LINE__. |
msg |
in | Pre-formatted message string (no trailing newline; the implementation adds one). NULL-safe (no-op). |
Success
Formats one line ("[LEVEL] [tag:line] msg\n") through a stack-local HeapAllocator, writes it via a single FileWrite to fd 1 (INFO) or fd 2 (ERROR / FATAL), and for FATAL appends a captured backtrace; releases the transient Str + allocator and returns.
Failure
Returns without writing if msg is NULL. Underlying FileWrite errors are dropped (the logger is best-effort by design; there is no upstream reporter to surface to).
Usage example (Cross-references)
Usage examples (Cross-references)
// no formatting, no shared state.
__attribute__((weak, used, noreturn)) void __stack_chk_fail(void) {
LogWrite(
LOG_MESSAGE_TYPE_FATAL,
"__stack_chk_fail",- In
Log.c:39:
#endif
void LogWrite(LogMessageType type, Zstr tag, u64 line, Zstr msg) {
if (!msg) {
return;- In
Log.h:45:
Str UNPL(m) = StrInit(&UNPL(log_alloc)); \
StrAppendFmt(&UNPL(m), __VA_ARGS__); \
LogWrite(LOG_MESSAGE_TYPE_FATAL, __func__, __LINE__, StrBegin(&UNPL(m))); \
StrDeinit(&UNPL(m)); \
HeapAllocatorDeinit(&UNPL(log_alloc)); \
- In
Log.h:69:
Str UNPL(m) = StrInit(&UNPL(log_alloc)); \
StrAppendFmt(&UNPL(m), __VA_ARGS__); \
LogWrite(LOG_MESSAGE_TYPE_ERROR, __func__, __LINE__, StrBegin(&UNPL(m))); \
StrDeinit(&UNPL(m)); \
HeapAllocatorDeinit(&UNPL(log_alloc)); \
- In
Log.h:92:
Str UNPL(m) = StrInit(&UNPL(log_alloc)); \
StrAppendFmt(&UNPL(m), __VA_ARGS__); \
LogWrite(LOG_MESSAGE_TYPE_INFO, __func__, __LINE__, StrBegin(&UNPL(m))); \
StrDeinit(&UNPL(m)); \
HeapAllocatorDeinit(&UNPL(log_alloc)); \
- In
Log.h:131:
StrAppendFmt(&UNPL(m), " : {}", UNPL(syserr)); \
} \
LogWrite(LOG_MESSAGE_TYPE_FATAL, __func__, __LINE__, StrBegin(&UNPL(m))); \
StrDeinit(&UNPL(m)); \
HeapAllocatorDeinit(&UNPL(log_alloc)); \
- In
Log.h:160:
StrAppendFmt(&UNPL(m), " : {}", UNPL(syserr)); \
} \
LogWrite(LOG_MESSAGE_TYPE_ERROR, __func__, __LINE__, StrBegin(&UNPL(m))); \
StrDeinit(&UNPL(m)); \
HeapAllocatorDeinit(&UNPL(log_alloc)); \
- In
Log.h:188:
StrAppendFmt(&UNPL(m), " : {}", UNPL(syserr)); \
} \
LogWrite(LOG_MESSAGE_TYPE_INFO, __func__, __LINE__, StrBegin(&UNPL(m))); \
StrDeinit(&UNPL(m)); \
HeapAllocatorDeinit(&UNPL(log_alloc)); \
- In
Log.h:222:
///
#define ASSERT_OR_FATAL(cond, msg) \
((cond) ? 0 : (LogWrite(LOG_MESSAGE_TYPE_FATAL, __func__, __LINE__, (msg)), Abort(), 0))
///
Last updated on