libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_dump.h
1/*-
2 * Copyright (c) 2026, The XTC Project
3 * Use of this source code is governed by the ISC License.
4 *
5 * src/inc/xtc_dump.h
6 * Crash diagnostics: a runtime-state dump (the programmatic form of
7 * the debugger's xtc-procs / xtc-loops / xtc-mailbox), plus panic and
8 * assert macros that emit it before aborting, and an optional fatal-
9 * signal handler that emits it on SIGSEGV / SIGBUS / SIGABRT.
10 *
11 * xtc_dump writes, to a file descriptor:
12 * - the C backtrace of the CALLING (faulting) OS thread, when a
13 * backtrace backend is compiled in (see os_backtrace.h);
14 * - every scheduler loop with its run-queue / steal stats;
15 * - every live proc with its run state, park reason, and mailbox
16 * depth / peak / recv / drop counters.
17 * The field labels match the debugger scripts (tools/gdb,
18 * tools/lldb), so an in-process dump and a gdb session read alike.
19 *
20 * A parked fiber's OWN C stack is NOT unwound: it lives in a saved
21 * coroutine context, not on a live OS thread. Like an Erlang crash
22 * dump or a Go panic, the dump reports each proc's state and mailbox,
23 * not N reconstructed C stacks. For deep per-fiber stacks attach a
24 * debugger to a core (the dump and the debugger share field names).
25 *
26 * Signal-safety: xtc_dump takes the per-loop inspection locks (via
27 * xtc_inspect), so it is fully reliable from an explicit XTC_PANIC /
28 * XTC_ASSERT in normal context. From the fatal-signal handler the
29 * backtrace (async-signal-safe) is always emitted; the proc/loop walk
30 * is attempted best-effort and may be skipped if a lock was held at
31 * the moment of the fault. See docs/guide/debugging.md.
32 */
33
34#ifndef XTC_DUMP_H
35#define XTC_DUMP_H
36
37#include "xtc.h"
38
39#if defined(__GNUC__) || defined(__clang__)
40# define XTC_NORETURN __attribute__((noreturn))
41#else
42# define XTC_NORETURN
43#endif
44
45/*
46 * PUBLIC: void xtc_dump __P((int));
47 * PUBLIC: void xtc_panic __P((const char *, int, const char *, ...));
48 * PUBLIC: int xtc_crash_handler_install __P((void));
49 */
50
51/* Write a best-effort runtime-state dump to file descriptor `fd`
52 * (commonly STDERR_FILENO). Never allocates; safe to call at any
53 * time. Does not abort -- callers decide what to do next. */
54void xtc_dump(int fd);
55
56/* Emit `fmt`/... as a panic banner, then xtc_dump(STDERR_FILENO), then
57 * abort(). Use the XTC_PANIC macro rather than calling directly. */
58void xtc_panic(const char *file, int line, const char *fmt, ...) XTC_NORETURN;
59
60/* Install a fatal-signal handler (SIGSEGV, SIGBUS, SIGABRT, SIGFPE,
61 * SIGILL) that emits a backtrace + best-effort runtime dump to stderr,
62 * then re-raises the signal with the default disposition (so a core is
63 * still produced). Returns XTC_OK, or XTC_E_NOSYS where unsupported.
64 * Idempotent. Does NOT install SIGCHLD/SIGTERM/etc. -- only faults. */
65int xtc_crash_handler_install(void);
66
67/* Log `fmt`/..., dump runtime state, and abort. */
68#define XTC_PANIC(...) xtc_panic(__FILE__, __LINE__, __VA_ARGS__)
69
70/* Abort with a dump unless `cond` holds. */
71#define XTC_ASSERT(cond) \
72 do { if (!(cond)) \
73 xtc_panic(__FILE__, __LINE__, "assertion failed: %s", #cond); \
74 } while (0)
75
76/* Like XTC_ASSERT but with a custom printf-style message. */
77#define XTC_ASSERT_F(cond, ...) \
78 do { if (!(cond)) xtc_panic(__FILE__, __LINE__, __VA_ARGS__); } while (0)
79
80#endif /* XTC_DUMP_H */