You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix macOS crash in GetAvailableServers (CGo write barrier) (#8541)
* Fix macOS crash in GetAvailableServers due to CGo write barrier panic
GetAvailableServers was crashing with a runtime.throw in
bulkBarrierPreWrite when called from Swift via gomobile. The Servers()
return value contains pointer-rich types (Options with any interfaces)
whose copy triggers GC write barriers on the CGo callback stack, which
the GC heap bitmap doesn't cover.
Move the Servers() + json.Marshal work to a dedicated goroutine so it
runs on a proper Go stack where write barriers function correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix getAutoLocation in FFI and mobile for same CGo write barrier issue
Apply the same goroutine-based fix to getAutoLocation() in both
ffi/ffi.go and mobile/mobile.go. These functions marshal Server types
containing pointer-rich Options interfaces, which can trigger GC write
barrier panics on the CGo callback stack.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Extract RunOnGoStack helper, add panic recovery
Address PR review feedback:
- Extract a generic RunOnGoStack[T] helper in utils/gostack.go that runs
a closure on a dedicated goroutine and returns the result via channel.
Includes defer/recover so a panic in the closure returns an error
instead of blocking the caller forever.
- Refactor all three call sites (GetAvailableServers, getAutoLocation in
FFI, GetAutoLocation in mobile) to use the shared helper.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Use radiance's CGo-safe JSON methods, remove local helper
Move the CGo safety concern into radiance where the pointer-rich types
originate. Callers now use ServersJSON() and GetServerByTagJSON() which
marshal internally and return plain []byte.
- Remove utils/gostack.go (moved to radiance common/gostack.go)
- GetAvailableServers uses Manager.ServersJSON()
- getAutoLocation (FFI) and GetAutoLocation (mobile) use
Core.GetServerByTagJSON() which delegates to Manager.GetServerByTagJSON()
- Upgrade radiance to 477c01d which adds the new methods
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Simplify: remove wasteful debug log, update radiance
- Remove slog.Debug that converted potentially large []byte to string on
every GetAvailableServers call regardless of log level
- Update radiance to 405169d which extracts shared lookup logic and uses
MarshalContext consistently
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove GetServerByTag from App interface
All callers are internal to lantern-core and access serverManager
directly. Removing the unnecessary interface method and delegation
wrapper simplifies the API surface — external callers should use
GetServerByTagJSON which is CGo-safe.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Run go mod tidy
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add goroutine hop for gomobile-exported functions
The previous fix (using ServersJSON/GetServerByTagJSON) moved the
marshal inside radiance but didn't address the root cause: the crash
is in the gomobile-generated CGo wrapper (_cgoexp_proxymobile__*),
which copies Go pointer-containing return values to the C thread
stack. The GC heap bitmap doesn't cover that memory, so
bulkBarrierPreWrite panics.
The only reliable fix is to run the entire function body on a real Go
goroutine stack via runOffCgoStack. The goroutine result is sent back
through a channel (which only involves copying the final []byte/string,
not pointer-rich intermediate types).
The FFI path (ffi.go) doesn't need this because its //export functions
return *C.char (C-allocated memory, no GC pointers).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Use radiance's common.RunOffCgoStack, remove local copy
Move the goroutine hop helper to radiance so any project consuming
radiance through gomobile can use it. Replace the local runOffCgoStack
in mobile.go with common.RunOffCgoStack.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove RunOffCgoStack wrappers from mobile.go
ServersJSON and GetServerByTagJSON in radiance now handle the goroutine
hop internally, so callers don't need to wrap anything. mobile.go goes
back to straightforward delegation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Point to radiance main (bf610b5) after PR #361 merged
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* update radiance.
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Jigar-f <jigar@getlantern.org>
0 commit comments