Update deps, fix workspace hotpatching, add crash recovery#1
Open
enomado wants to merge 6 commits into
Open
Conversation
…dency - bump egui/eframe 0.32 → 0.34.1, subsecond 0.7.0-rc.0 → 0.7.4 - replace dioxus-devtools with lightweight connect_subsecond() reimplementation using only subsecond + dioxus-cli-config + tungstenite (avoids pulling full Dioxus stack) - adapt to eframe 0.34 new App::ui() API (replaces App::update()) - remove "workspace not supported" comment — workspace hotpatching landed in subsecond 0.7.x Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…::call Two fixes that enable workspace crate hotpatching on Linux: 1. Add .cargo/config.toml with `-Wl,--export-dynamic` for x86_64-linux. dx only exports the `main` symbol (--export-dynamic-symbol,main), so dlopen-ed patch .so cannot resolve egui/std monomorphizations from the host binary → SIGSEGV or "undefined symbol" on workspace crate patch. Full --export-dynamic makes all symbols available to patch .so via PLT. 2. Remove nested subsecond::call in subsecond_fn — keep single call point in App::ui. Nested HotFn causes stale pointer jumps after patch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
HotFn::current(fn).call() doesn't work for workspace crates because after the first tip-crate patch, App::ui runs from the patch .so, and fn pointers resolve through .so's GOT — giving a .so address, not the original binary address that the jump table maps from. Solution: OnceLock captures the original fn pointer before any patch, then call_workspace_ui() does a direct lookup in get_jump_table().map to find the current patched address and calls it. Also removes subsecond dependency from workspace_crate (not needed — the tip crate handles all hotpatch mechanics). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Covers how subsecond works, why HotFn fails for workspace crates (GOT/.so address mismatch), the OnceLock + jump table solution, comparison with Bevy's approach, and Linux --export-dynamic fix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Panic in workspace crate code no longer kills the app — it shows a red error label in the UI. Fixing the code and saving applies the next hotpatch without restart. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <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.
Summary
dioxus-devtoolsdependency (causes compile errors viadioxus-core); reimplement devserver connection withdioxus-cli-config+tungstenite+serde_jsonworkspace_crate_uiwas not actually updating on hotpatchWhat was broken and why
1. eframe 0.34 API change
App::update()→App::ui(),CentralPanel::show()→show_inside(). Fixed by updating call sites.2.
dioxus-devtoolspulls indioxus-corewhich doesn't compileReplaced with a direct WebSocket connection to dx devserver (~30 lines), using only
dioxus-cli-configfor endpoint discovery.3. SIGSEGV on workspace hotpatch (Linux)
dxon Linux only exportsmain(--export-dynamic-symbol,main). The patch.socouldn't resolve egui/std monomorphizations from the main binary → invalid pointer → crash.Fix:
.cargo/config.tomlwith--export-dynamicto export all symbols.4. Workspace crate text not updating after hotpatch
This was the hardest bug. Three layers:
subsecond::callinside workspace crate — ZST closure'scall_itis not in the jump table diff → removedHotFn::current(workspace_fn).call()doesn't work — after the first tip-crate patch,App::uiruns from the patch.so. Inside the.so,workspace_crate_uiresolves through.so's GOT giving a.soaddress, but the jump table mapsoriginal_binary_addr → new_addr. SoHotFn::call_as_ptrgets the.soaddress, doesn't find it in the jump table, and calls the old version.Solution:
OnceLockcaptures the original fn pointer before any patch.call_workspace_ui()does a direct lookup insubsecond::get_jump_table().mapwith this original address.How Bevy compares
Bevy's
#[hot]macro generatesHotFn::current(fn).call()per system — but they don't support workspace crates at all ("only patches the tip crate"). OurOnceLock+ jump table approach is the first working solution for workspace hotpatching.Tested scenarios
All verified working on Linux (x86_64):
Test plan
dx serve --hot-patchstarts and builds successfullysrc/my_component.rs→ changes appear in ~1sworkspace_crate/src/lib.rs→ changes appear in ~1spanic!()to workspace crate → app shows red error, doesn't crash🤖 Generated with Claude Code