Skip to content

fix(desktop-gpui): stop the Touch Bar finder's KVO exception from crashing the app - #2699

Merged
richiemcilroy merged 2 commits into
mainfrom
fix/gpui-touch-bar-finder-crash
Oct 19, 2026
Merged

richiemcilroy merged 2 commits into
mainfrom
fix/gpui-touch-bar-finder-crash

Conversation

@richiemcilroy

@richiemcilroy richiemcilroy commented Oct 18, 2026 •

Copy link
Copy Markdown
Member

A user on a 2020 Intel MacBook Pro with a Touch Bar (MacBookPro16,3, macOS 15.7.9) reported that the GPUI app (0.6.2-nightly.202610101017) crashed every time they started a recording, in every capture mode. The crash is an Objective-C exception that AppKit itself throws and then turns into a crash:

Exception Type:  EXC_BAD_INSTRUCTION (SIGILL)
Application Specific Backtrace 0:
  objc_exception_throw
  -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:context:]
  -[_NSTouchBarFinderObservation invalidate]
  ___NSTouchBarFinderSetNeedsUpdateOnMain_block_invoke_2
  NSDisplayCycleFlush
  CA::Transaction::commit()
Thread 0 Crashed:
  -[NSApplication _crashOnException:]

On Macs with a Touch Bar, AppKit's Touch Bar finder watches the key window's responder chain with key-value observing. Starting a recording hides and closes several windows at once (main window, target overlays), and when the finder rebuilds its observation during the next display-cycle flush, removing an old observer throws "Cannot remove an observer ... because it is not registered as an observer". AppKit catches that in its CATransaction commit handler and calls _crashOnException:. Cap never puts anything on the Touch Bar, and the exception is raised inside AppKit, so nothing in Cap's own code can catch it today.

Fix

  • -[_NSTouchBarFinderObservation invalidate] is routed through a guard at startup (platform/macos_exception_guard.rs). The guard calls the original implementation and, if it throws, logs the exception's name and reason and returns.
  • The @try/@catch is in a small Objective-C file, native/exception_guard.m, built by build.rs on macOS only. An Objective-C exception must not unwind through a Rust frame (Rust aborts), so the original method is called from Objective-C with no Rust frame between the throw and the catch. objc2's own catch would need its nightly-only unstable-c-unwind feature to be safe here.
  • If AppKit ever drops the class or method, the guard logs that there is nothing to guard and installs nothing.

Dropping a failed teardown leaves at most one stale observation in AppKit's Touch Bar bookkeeping. Modern Foundation removes observers when the observed object is deallocated, and Cap shows nothing on the Touch Bar, so nothing user-visible depends on it.

Tests

  • an_unbalanced_kvo_removal_throws_the_reported_exception reproduces the report's exception (removing a KVO observer that was never added) and checks the trampoline catches it with the same reason text.
  • a_guarded_method_survives_the_exception_every_time installs the guard on a test class whose invalidate throws that exception, then calls it three times. Without the guard the test process aborts.
  • appkit_still_has_the_touch_bar_finder_method_this_guards fails if a macOS update renames _NSTouchBarFinderObservation or invalidate, so the guard cannot silently stop applying.
  • Launching the app logs guarded the Touch Bar finder's observation teardown on macOS 27 (Apple Silicon).

I could not reproduce the crash itself: this needs Touch Bar hardware. The fix does not depend on what triggers the exception, only on where AppKit throws it.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no new actionable issues were found.

Summary

This PR catches the Touch Bar finder's teardown exception before it can crash the app.

  • The GPUI app catches Touch Bar teardown exceptions before they crash it.

Reviews (4) · Last reviewed commit: "fix(desktop-gpui): count exception-guard..." · Reviewed by Greptile

@vercel

vercel Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cap-status Ready Ready Preview Oct 18, 2026 5:43pm UTC

@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

Comment thread apps/desktop-gpui/native/exception_guard.m Outdated
Comment thread apps/desktop-gpui/src/platform/macos_exception_guard.rs Outdated
@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

@richiemcilroy
richiemcilroy marked this pull request as ready for review October 19, 2026 09:02

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

View 1 other finding in Capy.

Open in Capy

@richiemcilroy
richiemcilroy merged commit 88b0e7c into main Oct 19, 2026
66 checks passed

This branch was successfully deployed

2 active deployments
Preview – cap-web — 352aabce Deployed Oct 18, 2026 by vercel[bot]
Preview – cap-status — 352aabce Deployed Oct 18, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant