Skip to content

Fix CGo write barrier crashes: move split tunnel + API methods to radiance with RunOffCgoStack#8556

Merged
myleshorton merged 5 commits intomainfrom
fix/cgo-write-barrier-split-tunnel
Mar 23, 2026
Merged

Fix CGo write barrier crashes: move split tunnel + API methods to radiance with RunOffCgoStack#8556
myleshorton merged 5 commits intomainfrom
fix/cgo-write-barrier-split-tunnel

Conversation

@myleshorton
Copy link
Contributor

@myleshorton myleshorton commented Mar 20, 2026

Summary

  • Moves GetSplitTunnelItems and GetEnabledApps logic into radiance (SplitTunnel.ItemsJSON / SplitTunnel.EnabledAppsJSON), keeping lantern-core as thin wrappers
  • Wraps all []byte-returning APIClient methods in radiance with RunOffCgoStack: UserData, FetchUserData, Login, Logout, DeleteAccount, OAuthLoginCallback
  • Bumps radiance to pick up all fixes

Motivation

Gomobile-exported functions run on a CGo callback stack whose memory is not covered by the GC heap bitmap. When these methods allocate protobuf structs, maps, or slices and marshal them to []byte, bulkBarrierPreWrite panics when copying the return value across the C boundary.

The crash log from #3088 shows:

runtime.throw → bulkBarrierPreWrite → wbMove → _cgoexp_985d40ed99b5_proxymobile__GetSplitTunnelItems

Changes

lantern-core/core.go:

  • GetSplitTunnelItems → thin wrapper calling st.ItemsJSON(filterType)
  • GetEnabledApps → thin wrapper calling st.EnabledAppsJSON()

radiance (companion PR getlantern/radiance#363):

  • SplitTunnel.ItemsJSON / EnabledAppsJSON — new methods with RunOffCgoStack
  • APIClient.UserData, FetchUserData, Login, Logout, DeleteAccount, OAuthLoginCallback — all wrapped with RunOffCgoStack

Test plan

  • macOS launch no longer crashes with split tunnel enabled
  • Split tunnel UI loads correctly on all platforms
  • Login/logout/OAuth/purchase flows work
  • Existing radiance tests pass (new tests added in radiance#363)

Fixes getlantern/engineering#3088

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings March 20, 2026 13:02
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR mitigates macOS CGo write-barrier panics by ensuring LanternCore methods that allocate pointer-bearing Go values don’t run on the CGo callback stack.

Changes:

  • Wrap LanternCore.GetSplitTunnelItems with common.RunOffCgoStack to move slice allocation/JSON marshaling off the CGo callback stack.
  • Wrap LanternCore.GetEnabledApps with common.RunOffCgoStack to move map/slice allocations and JSON parsing/marshaling off the CGo callback stack.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Move the complex logic into radiance's SplitTunnel (ItemsJSON and
EnabledAppsJSON methods), keeping lantern-core as thin wrappers.
Both radiance methods use RunOffCgoStack internally to avoid CGo
write barrier panics on macOS.

Bumps radiance to pick up the new SplitTunnel methods.

Fixes getlantern/engineering#3088

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@myleshorton myleshorton force-pushed the fix/cgo-write-barrier-split-tunnel branch from 326e61e to 4c26b37 Compare March 20, 2026 13:10
@Derekf5
Copy link

Derekf5 commented Mar 20, 2026

@myleshorton FYI Just hit the same crash again but on UserData this time.

myleshorton and others added 2 commits March 20, 2026 07:18
Picks up RunOffCgoStack wrapping for UserData() and FetchUserData()
which also deserialize protobuf structs on the CGo callback stack.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Picks up RunOffCgoStack wrapping for Login, Logout, DeleteAccount,
and OAuthLoginCallback in addition to UserData and FetchUserData.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@myleshorton
Copy link
Contributor Author

@myleshorton FYI Just hit the same crash again but on UserData this time.

OK thanks added a fix for that too as well as other methods. Good you're catching these, as they theoretically aren't just Mac bugs.

@myleshorton myleshorton changed the title Fix CGo write barrier crash in GetSplitTunnelItems and GetEnabledApps Fix CGo write barrier crashes: move split tunnel + API methods to radiance with RunOffCgoStack Mar 20, 2026
Resolves go.mod/go.sum conflicts by taking main's versions then
updating radiance to the branch with ItemsJSON/EnabledAppsJSON methods
that this PR depends on.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@myleshorton
Copy link
Contributor Author

Call chain verification

Both radiance methods are fully wired through to the Dart UI:

Radiance method Lantern-core wrapper FFI (desktop) Mobile (gomobile) Dart
ItemsJSON GetSplitTunnelItems getSplitTunnelItems (ffi.go:948) GetSplitTunnelItems (mobile.go:528) Both FFI + platform service
EnabledAppsJSON GetEnabledApps getEnabledApps (ffi.go:998) N/A (desktop-only feature) FFI service only

The PR replaces ~90 lines of duplicated logic in lantern-core with thin wrappers that delegate to the CGo-safe radiance implementations.

Replaces branch pseudo-version with radiance main which now includes
both the bandit URL override wiring (#333) and the CGo-safe
ItemsJSON/EnabledAppsJSON methods (#363).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@myleshorton myleshorton merged commit 07e1728 into main Mar 23, 2026
9 checks passed
@myleshorton myleshorton deleted the fix/cgo-write-barrier-split-tunnel branch March 23, 2026 18:57
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.

3 participants