feat(crashdump): add Crashdump pillar browsing erl_crash.dump files#59
Merged
Conversation
Adds a web crash dump browser - the last big item from the observer_cli / OTP-observer gap-closing plan. Pick a dump, watch the parse progress live, then read the crash slogan, the VM's counters at crash time, and every dumped process: sortable by memory, reductions or message queue, searchable, with a drill-down showing the full per-process record including the stack dump and message queue. Parsing reuses OTP's own crashdump_viewer gen_server (observer app) instead of reimplementing the dump format - no GUI/wx is ever started. A dedicated ObserverWeb.Crashdump.Server owns the parser: it starts it on demand, serializes loads, and receives the parser's progress reports through a small linked relay process registered under the name the parser reports to (a process can only carry one registered name), re-broadcast over PubSub so the page renders a live progress bar. Records are decoded by zipping documented field orders over the tuples, degrading gracefully across OTP record evolution, and pids round-trip through the parser's own textual form. Safety and availability follow the established patterns: there is no free path input - only files in explicitly allowlisted crashdump_dirs are browsable, and with no configuration the page stays off (dumps hold everything the VM had at crash time; documented with a warning). Hosts without the observer application get a graceful notice; dev and test load it via Mix.ensure_application!/1. Dialyzer cannot see the pruned observer app, so the crashdump_viewer calls are ignore-listed with a comment explaining why they are safe. Tests exercise the full pipeline against a real crash dump generated by halting a peer node - listing, allowlist rejection, progress, general info (slogan), process summaries, details round-trip, and the page flow from LOAD to the stack dump panel.
Addresses the concern about the :observer dependency by making the whole
feature - including its navigation tab - opt-in behind a single flag,
and by adding file upload so a dump can be inspected without any
server-side directory:
* config :observer_web, crashdump: true gates the pillar. Off by
default the tab never appears; the page (if reached directly)
explains how to enable it. When on but :observer isn't in the
release, it explains that instead.
* Upload an erl_crash.dump straight from the browser (e.g. one pulled
off a crashed Nerves device) - it is copied to a temporary path the
parser re-reads for the session and the previous upload is cleaned
up. The directory listing is kept as a second, optional path and no
longer required.
The crashdump_dirs allowlist still governs host-side browsing (no free
path input); uploads are size-capped and consumed to a controlled temp
file. The nav also moves Crashdump ahead of Metrics so Metrics stays
last. Enabled in the dev server for convenience.
Real-upload parsing is covered end to end at the context level
(load_upload/1 against a dump from a crashed peer node); the page test
covers the upload UI and the validate/empty-submit handlers, since
simulating the upload channel through the nested LiveComponent hits a
test-harness limitation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The last big item from the observer_cli / OTP-observer gap-closing plan: a web crash dump browser - something no BEAM web tool offers today.
Pick an
erl_crash.dumpfrom the allowlisted directories, watch the parse progress live, then:How it works
:crashdump_viewer(observer app) is a plain gen_server behind the wx GUI - this feature drives it headless, so the notoriously tricky dump format is never reimplemented. No GUI/wx is ever started.ObserverWeb.Crashdump.Serverowns the parser lifecycle: starts it on demand, serializes loads, and receives progress through a small linked relay process holding the registered name the parser reports to (a process can carry only one registered name). Progress is re-broadcast over PubSub → live progress bar for multi-GB dumps.Safety & availability
config :observer_web, crashdump_dirs: [...]are browsable; with no configuration the page stays off. Documented with an explicit production-data warning (dumps hold process states, message queues, app data at crash time).:observerapp in their release get a graceful notice; dev/test load it viaMix.ensure_application!/1(Mix ≥1.15 path pruning).Risk assessment
:crashdump_viewerinternalscdv_progress_handler; clash if the cdv GUI is open on the same node:crashdump_viewercalls invisible to the PLT (path pruning)available?/0and covered by real-dump testsChecklist
mix format,credo --strict,dialyzer(exit 0), full suite 393 green ×3 seedserl_crash.dumpfrom a crashed peer nodecrashdump_dirsdocumented with security warningguides/static/crashdump_dash.pngscreenshot (needs a capture from a dev node before merge - configurecrashdump_dirsand crash a peer, or point it at any dump you have around)🤖 Generated with Claude Code