Repository navigation
sdk: a plugin's panic message reaches its crash report - #360
Merged
Merged
Conversation
A plugin dylib panicked through its own std: the message went to a stderr no report read, then abort() (on Windows RtlExitUserProcess, which no handler sees). The generated dylib root now declares `panic = sdk.dylib.panic`, which hands the message and first trace address to the host through the new EditorAPI.panic; fizzy raises it again as its own panic, so the crash report (or the web console) gets the message and frames from the panic site. Fingerprint recorded. Part of plans/RESTART_AND_CRASHES_PLAN.md, step 3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 10, 2026
Merged
foxnne
added a commit
that referenced
this pull request
Oct 11, 2026
## What changes `sdk_version` goes from 0.2.22 to 0.2.23. Merging tags `sdk-v0.2.23`, publishes its tarball, and asks the store plugins to repin. **Why now.** The plugin boundary's fingerprint moved since `sdk-v0.2.22` (`0x1bf417f6…` → `0x65096e94…`, by #360), so store plugins built against 0.2.22 don't load in a fizzy built from `main`, and fizzyed.it/app is built from `main`. Also, #355 moved the `plugins` service to version 2, and the agent plugin's `fizzy_build` asks for version 1 until it repins. ## SDK impact - [ ] None - [ ] Core-only or additive: reaches plugins at the next SDK release - [ ] Fingerprint moved: recorded in `sdk/src/version.zig`, `sdk_version` untouched, PR labelled `sdk` - [x] SDK release: bumps `sdk_version`, lists the `sdk` PRs since the last `sdk-v*` tag **The `sdk` PRs since `sdk-v0.2.22`:** - #360: a plugin's panic message reaches its crash report. This moves the fingerprint. **Additive, reaching plugins with this release:** - #355: the `plugins` service is version 2, with `list` (each plugin's identity, link, version, registration counts and status). A caller built for version 1 is refused until it rebuilds, which this release's repin does. - #351: a crash report says whose code crashed (`sdk/plugin_sdk.zig`). **Also reaching plugins (`core/`):** - `core.viz`, graphics for live numbers: `line`, `bar`, `stat`, `Table` (#345); `Pie`, `keyColor`, `palette` (#347); the table's rounded header and shaded rows (#359). - `core.profile`: - `lookback()`: 30 s of costs and the frames over budget, plus `ReportOptions.over_ms` / `.hitches` and `selfTimes` (#353). - `frameCauses()` and `ReportOptions.causes`: why each frame happened (#364). - `phase` / `Phases` / `ReportOptions.startup`: startup timing (#365, which landed inside #364's squash commit). - The profiler's `abi` stays 4. ## Verified - [x] macOS: - `zig build` and `test-sdk-version` on this head. - `scripts/pack-sdk.sh` packs `fizzy-sdk-v0.2.23.tar.gz`. - Every store plugin (fresh pulls of pixi, zig, drive, atlas and ghostty `main`) builds against this tree's `sdk/` with `zig build --fork=<sdk>` into a throwaway profile (31/31, and 28/28 for each of the other four). The fingerprint moved, so each repin PR is a real rebuild, but none should open as a draft for a broken build. The agent and chat plugins build too (22/22, 19/19). - [ ] Windows: - [ ] Linux: CI. - [ ] Web: ## Follow-ups - Each repin PR merged and its plugin tagged (the plugin repos' tags stay the maintainer's). - `fizzyedit/agent` and `fizzyedit/chat` repin to the `sdk-v0.2.23` tarball. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
foxnne
added a commit
that referenced
this pull request
Oct 11, 2026
## What changes **On the web, a plugin that fails to load now shows up as failed in the store's Installed pane, with the reason, as it does on the desktop.** Before, a refused build was only logged to the browser console. After #360 moved the SDK fingerprint, fizzyed.it/app refused every store plugin with `AbiMismatch`. The Installed pane listed each one as an undecided build with a **Load** button, and pressing Load failed silently in the same way. The desktop routes every load failure through `App.recordLoadFailure`, which feeds the failed card (reason, probed version, Retry/Reinstall/Uninstall) and the failed branch in Settings. The web's arrival path (`WebPluginRequest.arrived`) never did. It now records a failure on each of its three ways out: - the page could not fetch or link the module (offline, hash mismatch, not a side module); - `PluginLoader.prepare` refused it (fingerprint, SDK version, declared id, missing entry points); - its `register()` was rejected. When no build of that id is running (a remembered build coming back, a first install, a repair), the failure is recorded as a failed plugin. The card's detail line ("plugin x.y.z, min SDK a.b.c") comes from the module's own version getters through a new `PluginLoader_web.versionInfo`, which is the web's counterpart of `probeVersionInfo`. When a running build stays in front of a refused update, the failure is only noted for the `plugins` service, as a failed reload is on the desktop. The update window's row already turns to Retry in that case. A web load that succeeds now clears any earlier failure record, and so does a web uninstall, as both already do on the desktop. `App.pluginLoadFailureReason` now works with either loader's error set. The two sets share names where they mean the same thing, so the reasons live in a table keyed by error name and the switch is `inline else`. An error that either loader gains without a reason is still a compile error. The fingerprint problem itself needs an SDK release (0.2.23) and repins. That is separate from this PR. ## SDK impact - [x] None - [ ] Core-only or additive: reaches plugins at the next SDK release - [ ] Fingerprint moved: recorded in `sdk/src/version.zig`, `sdk_version` untouched, PR labelled `sdk` - [ ] SDK release: bumps `sdk_version`, lists the `sdk` PRs since the last `sdk-v*` tag ## Verified - [x] macOS: CI tests. - [x] Windows: CI tests and the cross-compiled build. - [x] Linux: CI tests, integration tests and verdict run. The Linux job also runs `zig build check-web`, so the wasm side compiles with the web loader's error set. - [ ] Web: not seen in a browser. I could not build the wasm app in the cloud session that wrote this, because its network policy blocks SDL's Linux dependency hosts. Still to check: load a store plugin built against SDK 0.2.22 on this build. Its card in the Installed tab should read "built against an incompatible Fizzy SDK" with Retry/Reinstall/Uninstall. ## Follow-ups - A refused build that the page never remembered (a first install this host refuses) has no URL to retry, so its card's Retry reports `NotUnloadable`. Reinstall from the store is the way back, as it is for any failed card with a store build. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_012tKz7NTwCwAPSmfg3DjHDX Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.
Part of
plans/RESTART_AND_CRASHES_PLAN.md, step 3 (crash reports). Follows #351.What changes
A plugin's panic now reaches fizzy's crash report, message included. Before, a plugin dylib panicked through its own copy of std. That printed the message to stderr, which the report never saw, and called
abort(). On macOS and Linux, #351's abort handler then wrotecrashed in <plugin>: Abortwith no message. On Windows, std's abort isRtlExitUserProcess(3), which no handler sees, so no report at all.Now the report reads:
The frames start at the plugin's panic site (
crashy+0x1b6ea3is0x12a2eaea3 in registerin std's trace), with noabort/libsystemframes in front.How:
sdk/plugin_sdk.zig, andplugins/shared/build/helpers.zigfor built-ins) declarespub const panic = sdk.dylib.panic. That isFullPanicover a forwarder, so every safety panic goes through it too.EditorAPI.panic.std.debug.panicExtra). Natively that is app: a crash report says whose code crashed #351'scrash.panic; on the web it is the web backend's handler, which logs to the console where a side module used to trap silently.sdk.runtime.installedHost(), new; the runtime's host pointer is now optional rather thanundefined), the dylib falls back to std's own handler.SDK impact
EditorAPIgainspanic; recorded0x65096e9408ddb32finsdk/src/version.zig,sdk_versionuntouched. Plugins get the forwarding at the next SDK release, once they rebuild against it. A plugin built against an older SDK keeps the old behavior, and the fingerprint keeps it from loading into a fizzy built from this commit.Verified
registeron request:fizzy crashed in crashy 0.3.1: panic: crashy was asked to panic, first framecrashy+0x1d173.crashed in crashy 0.3.1: Segmentation fault at address 0x10.zig build,zig build test(87/87 steps, 531/532, 1 skipped),test-integration(46/46 steps, 371/371),check-web,test-sdk-version.plugins/imagebuilds as a wasm side module (-Dtarget=wasm32-freestanding -Doptimize=ReleaseSmall) with the new root. Not run in a browser.Follow-ups
KeptDocuments.recoveredFromCheckpoint()), symbols by build id, and safe mode.🤖 Generated with Claude Code