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