Expand description
This file contains Bun’s crash handler. In debug builds, we are able to print backtraces that are mapped to source code. In release builds, we do not have debug symbols in the binary. Bun’s solution to this is called a “trace string”, a url with compressed encoding of the captured backtrace. Version 1 trace strings contain the following information:
- What version and commit of Bun captured the backtrace.
- The platform the backtrace was captured on.
- The list of addresses with ASLR removed, ready to be remapped.
- If panicking, the message that was panicked with.
These can be demangled using Bun’s remapping API, which has cached versions of all debug symbols for all versions of Bun. Hosting this keeps users from having to download symbols, which can be very large.
The remapper is open source: https://github.com/oven-sh/bun.report
A lot of this handler is based on the Zig Standard Library implementation for std.debug.panicImpl and their code for gathering backtraces.
Modules§
Structs§
- Action
Guard - RAII guard returned by
scoped_action/set_current_action_resolver. Restores the previousCURRENT_ACTIONon drop (Zig:defer current_action = old). - FmtAdapter
- Wrap a
core::fmt::Writesink (typically&mut core::fmt::Formatter) so it can be passed where a byte-levelWriteis expected. - Stack
Trace - Zig:
std.builtin.StackTrace— slice of return addresses + cursor. - Stored
Trace - Zig: src/crash_handler/crash_handler.zig::StoredTrace — fixed 31-frame buffer.
- Write
Stack Trace Limits - Zig:
WriteStackTraceLimits.
Enums§
- Action
- Crash
Reason - This structure and formatter must be kept in sync with
bun.report’s decoder implementation. - Trace
Seed - Where the crash trace is seeded from. Each call site has exactly one.
Constants§
- CURRENT_
ACTION - This can be set by various parts of the codebase to indicate a broader action being taken. It is printed when a crash happens, which can help narrow down what the bug is. Example: “Crashed while parsing /path/to/file.js”
Traits§
- Write
- Byte-level write sink — port of Zig
std.Io.Writer.
Functions§
- append_
pre_ crash_ handler - For large codebases such as bun.bake.DevServer, it may be helpful to dump a large amount of state to a file to aid debugging a crash.
- crash_
handler - This function is invoked when a crash happens. A crash is classified in
CrashReason. - current_
action - Snapshot the thread-local
CURRENT_ACTIONfor save/restore around a scoped operation (e.g.js_printer::print_with_writer_and_platform). - dump_
current_ stack_ trace - dump_
stack_ trace - Version of the standard library dumpStackTrace that has some fallbacks for cases where such logic fails to run.
- fix_
dead_ code_ elimination - handle_
root_ error - This is called when
mainreturns a Zig error. We don’t want to treat it as a crash under certain error codes. - init
- is_
panicking - panic_
impl - print_
metadata - remove_
pre_ crash_ handler - reset_
on_ posix - scoped_
action - Scoped
CURRENT_ACTION = action. Snapshots the previous value, installsaction, and returns anActionGuardthat restores the previous value on drop. Zig:const old = current_action; defer current_action = old; current_action = ...;. - set_
current_ action_ resolver - Scoped
CURRENT_ACTION = .resolver{...}. Zig (resolver.zig:672-679) sets this only underEnvironment.show_crash_tracebecause module resolution is extremely hot and has a low crash rate; the cfg-gate here mirrors that. - sleep_
forever_ if_ another_ thread_ is_ crashing - Zig: crash_handler.sleepForeverIfAnotherThreadIsCrashing.
- suppress_
core_ dumps_ if_ necessary - If POSIX, and the existing soft limit for core dumps (ulimit -Sc) is nonzero, change it to zero. Used in places where we intentionally crash for testing purposes so that we don’t clutter CI with core dumps.
- suppress_
reporting - From now on, prevent crashes from being reported to bun.report or the URL overridden in BUN_CRASH_REPORT_URL. Should only be used for tests that are going to intentionally crash, so that they do not fail CI due to having a crash reported. And those cases should guard behind a feature flag and call right before the crash, in order to make sure that crashes other than the expected one are not suppressed.
- write_
stack_ trace - Clone of
debug.writeStackTrace, but can be configured to stop at either a frame count, or when hitting jsc LLInt Additionally, the printing function does not print the^, instead it highlights the word at the column. This Makes each frame take up two lines instead of three. - write_
u64_ as_ two_ vlqs