fix(macos): replace raw MenuChild pointer with Rc#361
Open
divanshu-go wants to merge 1 commit into
Open
Conversation
…ee crash The MudaMenuItem ObjC class stored a raw `Cell<*const MenuChild>` ivar pointing into the Rust heap. If the owning `Menu` was dropped or replaced while the native NSMenuItem was still visible (e.g. Screenpipe rebuilding the tray menu while it was open), clicking any stale item would dereference freed memory — manifesting as a panic in `String::as_str` or `slice::from_raw_parts` inside `fire_menu_item_click`. Replace the ivar with `RefCell<Option<Rc<RefCell<MenuChild>>>>`. Each `create_ns_item_for_*` function now receives a cloned `Rc` of the owning `MenuChild` and stores it on the NSMenuItem. AppKit retains the NSMenuItem, so the `Rc` keeps the `MenuChild` alive for exactly as long as the native item exists — no lifetime mismatch possible. Fixes: tauri-apps#328
divanshu-go
added a commit
to divanshu-go/screenpipe
that referenced
this pull request
Jun 4, 2026
muda's macOS backend stored a raw `Cell<*const MenuChild>` ivar on every NSMenuItem. When Screenpipe rebuilt the tray menu while it was open, the old MenuChild items were freed but AppKit kept the NSMenuItems alive. A user click on the stale menu would dereference freed memory inside `fire_menu_item_click` — an `extern "C"` nounwind callback — making `catch_unwind` useless and aborting the process immediately. Symptom: PANIC at alloc/src/vec/mod.rs:1599 — unsafe precondition violated: slice::from_raw_parts requires the pointer to be aligned and non-null Fix (three layers): 1. Patch muda at source via [patch.crates-io]: divanshu-go/muda@fix/macos-menu-item-use-after-free replaces Cell<*const MenuChild> with RefCell<Option<Rc<RefCell<MenuChild>>>>. The Rc clone stored on NSMenuItem keeps MenuChild alive for exactly as long as AppKit retains the native item. Upstream PR: tauri-apps/muda#361 Root cause: tauri-apps/muda#328 2. Pending-menu pattern in tray.rs (macOS only): The background poller now queues (MenuState, TrayMenuData) into PENDING_TRAY_MENU instead of calling set_menu directly. A new on_tray_icon_event handler fires on MouseButtonState::Down — before AppKit opens the native menu — and installs the fresh menu then. Windows/Linux keep the existing immediate-update path. 3. Atomic icon update in safe_icon.rs: Both icon helpers now use set_icon_with_as_template(...) to set the image and template flag in one atomic call, closing a brief window where dark-mode tearing could occur. Also bumps Tauri to 2.11.2 (Rust) / 2.11.0 (npm) and aligns tauri-build, tauri-utils, @tauri-apps/cli to the same minor to resolve the version-mismatch build warning.
louis030195
pushed a commit
to screenpipe/screenpipe
that referenced
this pull request
Jun 4, 2026
* fix(tray): eliminate macOS use-after-free crash on menu click muda's macOS backend stored a raw `Cell<*const MenuChild>` ivar on every NSMenuItem. When Screenpipe rebuilt the tray menu while it was open, the old MenuChild items were freed but AppKit kept the NSMenuItems alive. A user click on the stale menu would dereference freed memory inside `fire_menu_item_click` — an `extern "C"` nounwind callback — making `catch_unwind` useless and aborting the process immediately. Symptom: PANIC at alloc/src/vec/mod.rs:1599 — unsafe precondition violated: slice::from_raw_parts requires the pointer to be aligned and non-null Fix (three layers): 1. Patch muda at source via [patch.crates-io]: divanshu-go/muda@fix/macos-menu-item-use-after-free replaces Cell<*const MenuChild> with RefCell<Option<Rc<RefCell<MenuChild>>>>. The Rc clone stored on NSMenuItem keeps MenuChild alive for exactly as long as AppKit retains the native item. Upstream PR: tauri-apps/muda#361 Root cause: tauri-apps/muda#328 2. Pending-menu pattern in tray.rs (macOS only): The background poller now queues (MenuState, TrayMenuData) into PENDING_TRAY_MENU instead of calling set_menu directly. A new on_tray_icon_event handler fires on MouseButtonState::Down — before AppKit opens the native menu — and installs the fresh menu then. Windows/Linux keep the existing immediate-update path. 3. Atomic icon update in safe_icon.rs: Both icon helpers now use set_icon_with_as_template(...) to set the image and template flag in one atomic call, closing a brief window where dark-mode tearing could occur. Also bumps Tauri to 2.11.2 (Rust) / 2.11.0 (npm) and aligns tauri-build, tauri-utils, @tauri-apps/cli to the same minor to resolve the version-mismatch build warning. * build(tray): pin muda fork by commit instead of branch The muda patch tracked a mutable branch, so a fresh `cargo update -p muda` or from-scratch lock regen would silently follow the fork's branch HEAD. Pin the exact commit (9dc5de5, unchanged) for reproducible builds, matching the existing `tauri-helper` rev-pin convention. Resolved graph is identical. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Louis Beaumont <louis@screenpi.pe> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
divanshu-go
added a commit
to divanshu-go/screenpipe
that referenced
this pull request
Jun 4, 2026
…pipe#3813) * fix(tray): eliminate macOS use-after-free crash on menu click muda's macOS backend stored a raw `Cell<*const MenuChild>` ivar on every NSMenuItem. When Screenpipe rebuilt the tray menu while it was open, the old MenuChild items were freed but AppKit kept the NSMenuItems alive. A user click on the stale menu would dereference freed memory inside `fire_menu_item_click` — an `extern "C"` nounwind callback — making `catch_unwind` useless and aborting the process immediately. Symptom: PANIC at alloc/src/vec/mod.rs:1599 — unsafe precondition violated: slice::from_raw_parts requires the pointer to be aligned and non-null Fix (three layers): 1. Patch muda at source via [patch.crates-io]: divanshu-go/muda@fix/macos-menu-item-use-after-free replaces Cell<*const MenuChild> with RefCell<Option<Rc<RefCell<MenuChild>>>>. The Rc clone stored on NSMenuItem keeps MenuChild alive for exactly as long as AppKit retains the native item. Upstream PR: tauri-apps/muda#361 Root cause: tauri-apps/muda#328 2. Pending-menu pattern in tray.rs (macOS only): The background poller now queues (MenuState, TrayMenuData) into PENDING_TRAY_MENU instead of calling set_menu directly. A new on_tray_icon_event handler fires on MouseButtonState::Down — before AppKit opens the native menu — and installs the fresh menu then. Windows/Linux keep the existing immediate-update path. 3. Atomic icon update in safe_icon.rs: Both icon helpers now use set_icon_with_as_template(...) to set the image and template flag in one atomic call, closing a brief window where dark-mode tearing could occur. Also bumps Tauri to 2.11.2 (Rust) / 2.11.0 (npm) and aligns tauri-build, tauri-utils, @tauri-apps/cli to the same minor to resolve the version-mismatch build warning. * build(tray): pin muda fork by commit instead of branch The muda patch tracked a mutable branch, so a fresh `cargo update -p muda` or from-scratch lock regen would silently follow the fork's branch HEAD. Pin the exact commit (9dc5de5, unchanged) for reproducible builds, matching the existing `tauri-helper` rev-pin convention. Resolved graph is identical. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Louis Beaumont <louis@screenpi.pe> Co-authored-by: Claude Opus 4.8 <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.
The MudaMenuItem ObjC class stored a raw
Cell<*const MenuChild>ivar pointing into the Rust heap. If the owningMenuwas dropped or replaced while the native NSMenuItem was still visible (e.g. Screenpipe rebuilding the tray menu while it was open), clicking any stale item would dereference freed memory — manifesting as a panic inString::as_strorslice::from_raw_partsinsidefire_menu_item_click.Replace the ivar with
RefCell<Option<Rc<RefCell<MenuChild>>>>. Eachcreate_ns_item_for_*function now receives a clonedRcof the owningMenuChildand stores it on the NSMenuItem. AppKit retains the NSMenuItem, so theRckeeps theMenuChildalive for exactly as long as the native item exists — no lifetime mismatch possible.Fixes: #328