Fix SIGBUS/SIGSEGV crash in TemperaturesWithContext on macOS ARM64#2063
Conversation
ee973e6 to
801656c
Compare
shirou
left a comment
There was a problem hiding this comment.
Thank you! The fix for sensors is correct and well-motivated. Two follow-up concerns:
- The same open/close-on-every-call pattern exists in
cpu/cpu_darwin_arm64.goanddisk/disk_darwin.go— those should be fixed too (either in this PR or as a tracked follow-up). - With shared library handles,
library.fnMap(used insidegetFuncatinternal/common/common_darwin.go:44-54) access ingetFuncbecomes a potential data race under concurrent calls. Consider whether fnMap needs synchronization or if the function pointers should be resolved eagerly ininitSensorLibraries.
801656c to
ea57bfc
Compare
|
Updated the PR to address both concerns:
4 files changed, tested on Mac mini M2 Pro — agent stable for 4+ days with the fix. |
…a race Three changes: 1. sensors/sensors_darwin_arm64.go, cpu/cpu_darwin_arm64.go, disk/disk_darwin.go: Initialize IOKit and CoreFoundation libraries once via sync.Once instead of opening/closing them on every call. Dlclose invalidates library handles that the Go runtime (GC, timers, finalizers) may still reference, causing SIGBUS or SIGSEGV crashes. 2. internal/common/common_darwin.go: Make getFunc thread-safe via sync.RWMutex with double-checked locking. With shared library handles, concurrent calls to getFunc race on fnMap reads and writes. The fast path (read lock) avoids contention after function pointers are resolved on first call. The libraries are kept open for the process lifetime. They are small (~1 handle each) and macOS expects them to stay loaded. Tested on Mac mini M2 Pro, macOS Tahoe 26.3.1. Without the fix, the agent crashes within hours. With the fix, stable for 4+ days. Fixes shirou#1832 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ea57bfc to
76137fe
Compare
shirou
left a comment
There was a problem hiding this comment.
LGTM. Root cause is clear and the fix is correct — keeping framework handles open for the process lifetime is the right approach. The sync.RWMutex addition to getFunc properly addresses the data race from shared handles. Thanks!
Summary
Initialize IOKit and CoreFoundation libraries once via
sync.Onceinstead of opening/closing them on every call toTemperaturesWithContext.Problem
TemperaturesWithContextinsensors_darwin_arm64.gocallscommon.NewLibrary()+defer Close()on every invocation.Close()callspurego.Dlclose()which invalidates the library handles. The Go runtime (GC, timers, finalizers) can still reference these handles after close, causing:SIGBUS(bus error)SIGSEGV(segmentation fault)unexpected return pcruntime panicsThis affects all macOS ARM64 (Apple Silicon) systems: M1, M2, M4 confirmed.
Fix
The libraries are kept open for the process lifetime. They are small (~1 handle each) and macOS expects them to stay loaded.
Test
Tested on Mac mini M2 Pro, macOS Tahoe 26.3.1. Without the fix, the agent crashes within hours. With the fix, it runs stable for 24h+.
Related