xtc_dump(3)
---xtc_dump(3)
crash diagnostics: runtime-state dump, panic, fatal-signal handler
| XTC_DUMP(3) | Library Functions Manual | XTC_DUMP(3) |
NAME
xtc_dump,
xtc_panic,
xtc_crash_handler_install —
crash diagnostics: runtime-state dump, panic, fatal-signal
handler
SYNOPSIS
#include <xtc.h>
#include <xtc_dump.h>
void
xtc_dump(int
fd);
void
xtc_panic(const
char *file, int
line, const char
*fmt, ...);
int
xtc_crash_handler_install(void);
XTC_PANIC(fmt,
...);
XTC_ASSERT(cond);
XTC_ASSERT_F(cond,
fmt,
...);
DESCRIPTION
These routines turn the live runtime into a human-readable diagnostic on the way down, without a debugger or a core file. The dump is the in-process counterpart of the debugger scripts (xtc_proc(3), xtc_inspect(3)): the same proc, loop, and mailbox view an observer session shows, written to a file descriptor.
xtc_dump()
writes a best-effort runtime-state dump to fd
(commonly STDERR_FILENO):
- the C backtrace of the calling OS thread, when a backtrace backend is compiled in (see PORTABILITY);
- every scheduler loop with its run-queue and work-steal counters;
- every live proc with its run state, park reason, and mailbox depth, peak, capacity, and lifetime receive/drop counts.
xtc_dump() never allocates and never aborts; it writes
through a fixed stack buffer with raw write(2) calls, so it
can run at any time and does not perturb the heap it may be diagnosing. The
caller decides what to do next.
xtc_panic()
emits fmt/... as a panic banner,
then xtc_dump(STDERR_FILENO),
then calls abort(3). It does not return. Call it through
the
XTC_PANIC()
macro, which supplies file and
line:
XTC_PANIC("bad frame %ld: pin=%d", (long)idx, pin);
XTC_ASSERT()
panics with the failed expression when cond is false;
XTC_ASSERT_F()
does the same with a caller-supplied message. Unlike the standard
assert(3), both emit the full runtime dump before
aborting, and both are always compiled in (they are diagnostics, not
debug-only checks).
XTC_ASSERT(frame->pin > 0); XTC_ASSERT_F(n <= cap, "overflow: n=%zu cap=%zu", n, cap);
xtc_crash_handler_install()
installs a handler for the fatal signals SIGSEGV,
SIGBUS, SIGABRT,
SIGFPE, and SIGILL that
emits a backtrace and a best-effort runtime dump to standard error, then
re-raises the signal with its default disposition so a core is still
produced. It is idempotent and installs handlers only for faults -- never
for SIGCHLD, SIGTERM, or
other signals an embedder may manage. It returns
XTC_OK, or XTC_E_NOSYS on a
platform without POSIX signals.
SCOPE AND LIMITS
A parked fiber's own C stack is not unwound: it lives in a saved coroutine context, not on a live OS thread. Like an Erlang crash dump or a Go panic, the dump reports each proc's state and mailbox -- which proc is parked, on what, with how deep a mailbox -- not N reconstructed C stacks. Only the calling (faulting) thread's C stack is shown. For deep per-fiber stacks attach a debugger to a core; the dump and the debugger share field names so the two views line up.
This makes the facility strongest for the
failure mode it was built for: a hung or wedged message-passing system,
where the question is “which proc is waiting on whom, and why did it
not wake.” For domain data-structure invariants, keep using
XTC_ASSERT()
on those structures directly.
SIGNAL SAFETY
xtc_dump() takes the per-loop inspection
locks (via xtc_inspect(3)), so it is fully reliable from
an explicit
XTC_PANIC()
or XTC_ASSERT() in normal context. From the
fatal-signal handler the banner and backtrace are always emitted -- they use
only async-signal-safe primitives -- but the proc/loop walk is attempted
best-effort and may block if the fault happened while a loop lock was held.
A hung handler still leaves the banner and backtrace, and the re-raised
signal still yields a core.
PORTABILITY
The C backtrace uses the
__os_backtrace()
seam, selected at configure time in priority order: the
<execinfo.h>
backtrace()
backend on glibc, macOS, and the BSDs (symbolized frames); a
libunwind(3) backend where execinfo is absent (notably
musl), symbolized best-effort with dladdr(3) or
addresses-only when dladdr is unavailable; a Windows DbgHelp backend
(CaptureStackBackTrace(),
SymFromAddr()),
compiled and reviewed but not yet runtime-verified on a Windows host; and
otherwise a no-op stub. Where no backend is present the dump omits the C
stack but still reports the full proc/loop/mailbox state.
xtc_crash_handler_install() returns
XTC_E_NOSYS on Windows (SEH is future work).
RETURN VALUES
xtc_dump() returns nothing.
xtc_panic() does not return.
xtc_crash_handler_install() returns
XTC_OK, or XTC_E_NOSYS where
unsupported.
EXAMPLES
Install the crash handler at startup, then assert an invariant:
xtc_crash_handler_install(); ... XTC_ASSERT_F(pin > 0, "unfix underflow: frame=%ld", (long)idx);
SEE ALSO
AUTHORS
The xtc project.
| June 4, 2026 | Debian |