summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-03 13:10:59 -0300
committerGabriel Schneider <[email protected]>2026-09-03 13:10:59 -0300
commitffc8c1f6f19a5dc48e98f99938b438baf9a97165 (patch)
tree81ede7b26e6a1713597a236973014c1b64934d00 /docs
parent3f2d6f43199d0e230490396deb50f8dc49c7b8b0 (diff)
downloadpardes-ffc8c1f6f19a5dc48e98f99938b438baf9a97165.tar.gz
pardes-ffc8c1f6f19a5dc48e98f99938b438baf9a97165.zip
crash: a panic writes itself down beside the init file, where stderr cannot lose it
Every crash this program has ever had went to stderr and nowhere else, and stderr is the one place it cannot keep anything. In the tty shell stderr IS the screen, so the trace lands on the grid the terminal is being reset out of; the SDL and AppKit shells have no terminal at all; a --detach session's goes wherever its launcher left it. src/crash.zig appends a record to <config dir>/crashes first: one line naming the build (version, commit, UTC, os-arch, pid) and under it the panic message and the frames behind it. RETURN ADDRESSES and not the symbolised trace, which is measured rather than chosen. `std.debug.writeCurrentStackTrace` called from a panic handler BEFORE defaultPanic wedges the process at 0% CPU: symbolising reads DWARF, that read can itself panic, and the staging which turns a nested panic into "aborting due to recursive panic" is defaultPanic's own and private. Reproduced in a standalone build with this program's std_options_debug_io and inside a test binary. `captureCurrentStackTrace` only walks frames, so the addresses go in the file and `addr2line -e` finishes the job; stderr still gets the symbolised trace from defaultPanic, unchanged. The AppKit shell gets a panic handler of its own here too: the macOS build roots at macos.zig, so main.zig's had never run there — in the shell with the least useful stderr of the four. The config directory is COPIED rather than borrowed, because that host's lives in an arena its own errdefer frees. One record at a time, so two panicking threads cannot interleave into one buffer. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_016Q4RATpafkwahrovHQLKRf
Diffstat (limited to 'docs')
-rw-r--r--docs/config.md38
1 files changed, 38 insertions, 0 deletions
diff --git a/docs/config.md b/docs/config.md
index 7982ccee..b95f207e 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -93,6 +93,44 @@ and `ayu_mirage` is helix's `ayu_mirage.toml`. The suffix goes on all of them
rather than only the eight that clash today, so a name cannot move when either
project gains or loses a file. A name that is not in the ring is ignored.
+## Crash records
+
+A panic appends to `crashes` in that same directory, beside `init`, and only
+then prints to stderr (`src/crash.zig`, wired into the panic handlers in
+`main.zig` and — because the macOS build roots there — `macos.zig`). stderr is
+the one place this program cannot keep a trace: in the TTY shell stderr IS the
+screen, so the trace lands on a grid the terminal is being reset out of; the SDL
+and AppKit shells have no terminal at all; and a `--detach` session's stderr
+goes wherever its launcher left it. The file is appended, never rewritten, and
+each record is one line of build metadata, the panic message, and the return
+addresses behind it:
+
+```text
+pardes 0.0.2 (a1b2c3d) 2026-09-03T11:20:44Z linux-x86_64 pid 48812
+panic: index out of bounds: index 4, len 4
+ 0x11ccb5a
+ 0x11cc84c
+ 0x11cc67a
+```
+
+`addr2line -e <the pardes binary>` turns those into source lines, against the
+build the metadata line names. They are addresses rather than the symbolised
+trace stderr gets for a measured reason: symbolising from inside a panic
+handler, before `std.debug.defaultPanic` has run, HANGS the process — reading
+DWARF can itself panic, and the staging that turns a nested panic into
+"aborting due to recursive panic" is `defaultPanic`'s own and private. Walking
+frames is safe; symbolising them is not.
+
+Everything about it is best effort and silent: no config directory (a launch
+with no `HOME`) means no file, and a directory that cannot be created or opened
+leaves the panic exactly as it was before — stderr alone. The directory itself
+is created if it does not exist, because the user who never wrote an `init` is
+as likely as any other to hit a bug. One record at a time: two threads panicking
+at once would otherwise interleave into one buffer, so the second falls straight
+through to stderr. Only panics come here; a SIGSEGV is caught one level lower
+(`main.zig`'s `debug.handleSegfault`) and unwinding one needs the signal's saved
+CPU context.
+
## Runtime theme files
`ThemeFile <path>` loads one complete theme from a `.zon` file. An absolute