fix: memory leak and string corruption in ARM Mac temperature sensors

This commit addresses several issues in the temperature sensor implementation for ARM Mac:
1. Memory leak caused by unreleased system resources
2. Increasing port counts in Activity Monitor
3. String corruption where the first character becomes "\x00"

Changes:

1. Resource Management:
   - Added proper resource cleanup using `defer` statements
   - Refactored code to share the HID system client instead of creating new ones
   - Fixed memory leaks by ensuring all CoreFoundation objects are properly released

2. String Handling:
   - Fixed buffer allocation for string conversion
   - Properly handle null terminators in C string to Go string conversion
   - Added correct string length calculations

3. Code Structure:
   - Reduced resource allocation by sharing system client between functions
   - Enhanced code readability with better comments
pull/1767/head
Li Chuangbo 3 months ago
parent 90efec0764
commit 19082b35ae
No known key found for this signature in database

@ -41,11 +41,16 @@ func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
} }
ta.matching(0xff00, 5) ta.matching(0xff00, 5)
thermalNames := ta.getProductNames() defer ta.cfRelease(uintptr(ta.sensors))
thermalValues := ta.getThermalValues()
// Create HID system client
system := ta.ioHIDEventSystemClientCreate(common.KCFAllocatorDefault)
defer ta.cfRelease(uintptr(system))
thermalNames := ta.getProductNames(system)
thermalValues := ta.getThermalValues(system)
result := dumpNameValues(thermalNames, thermalValues) result := dumpNameValues(thermalNames, thermalValues)
ta.cfRelease(uintptr(ta.sensors))
return result, nil return result, nil
} }
@ -84,14 +89,12 @@ type temperatureArm struct {
sensors unsafe.Pointer sensors unsafe.Pointer
} }
func (ta *temperatureArm) getProductNames() []string { func (ta *temperatureArm) getProductNames(system unsafe.Pointer) []string {
ioHIDServiceClientCopyProperty := common.GetFunc[common.IOHIDServiceClientCopyPropertyFunc](ta.ioKit, common.IOHIDServiceClientCopyPropertySym) ioHIDServiceClientCopyProperty := common.GetFunc[common.IOHIDServiceClientCopyPropertyFunc](ta.ioKit, common.IOHIDServiceClientCopyPropertySym)
cfStringGetLength := common.GetFunc[common.CFStringGetLengthFunc](ta.cf, common.CFStringGetLengthSym) cfStringGetLength := common.GetFunc[common.CFStringGetLengthFunc](ta.cf, common.CFStringGetLengthSym)
cfStringGetCString := common.GetFunc[common.CFStringGetCStringFunc](ta.cf, common.CFStringGetCStringSym) cfStringGetCString := common.GetFunc[common.CFStringGetCStringFunc](ta.cf, common.CFStringGetCStringSym)
var names []string var names []string
system := ta.ioHIDEventSystemClientCreate(common.KCFAllocatorDefault)
ta.ioHIDEventSystemClientSetMatching(uintptr(system), uintptr(ta.sensors)) ta.ioHIDEventSystemClientSetMatching(uintptr(system), uintptr(ta.sensors))
matchingsrvs := ta.ioHIDEventSystemClientCopyServices(uintptr(system)) matchingsrvs := ta.ioHIDEventSystemClientCopyServices(uintptr(system))
@ -99,44 +102,44 @@ func (ta *temperatureArm) getProductNames() []string {
if matchingsrvs == nil { if matchingsrvs == nil {
return nil return nil
} }
defer ta.cfRelease(uintptr(matchingsrvs))
count := ta.cfArrayGetCount(uintptr(matchingsrvs)) count := ta.cfArrayGetCount(uintptr(matchingsrvs))
var i int32 var i int32
str := ta.cfStr("Product") str := ta.cfStr("Product")
defer ta.cfRelease(uintptr(str))
for i = 0; i < count; i++ { for i = 0; i < count; i++ {
sc := ta.cfArrayGetValueAtIndex(uintptr(matchingsrvs), i) sc := ta.cfArrayGetValueAtIndex(uintptr(matchingsrvs), i)
name := ioHIDServiceClientCopyProperty(uintptr(sc), uintptr(str)) name := ioHIDServiceClientCopyProperty(uintptr(sc), uintptr(str))
if name != nil { if name != nil {
length := cfStringGetLength(uintptr(name)) + 1 // null terminator length := cfStringGetLength(uintptr(name)) + 1 // include null terminator
buf := make([]byte, length-1) buf := make([]byte, length) // allocate buffer with full length
cfStringGetCString(uintptr(name), &buf[0], length, common.KCFStringEncodingUTF8) cfStringGetCString(uintptr(name), &buf[0], length, common.KCFStringEncodingUTF8)
names = append(names, string(buf)) names = append(names, string(buf[:length-1])) // remove null terminator
ta.cfRelease(uintptr(name)) ta.cfRelease(uintptr(name))
} else { } else {
names = append(names, "noname") names = append(names, "noname")
} }
} }
ta.cfRelease(uintptr(matchingsrvs))
ta.cfRelease(uintptr(str))
return names return names
} }
func (ta *temperatureArm) getThermalValues() []float64 { func (ta *temperatureArm) getThermalValues(system unsafe.Pointer) []float64 {
ioHIDServiceClientCopyEvent := common.GetFunc[common.IOHIDServiceClientCopyEventFunc](ta.ioKit, common.IOHIDServiceClientCopyEventSym) ioHIDServiceClientCopyEvent := common.GetFunc[common.IOHIDServiceClientCopyEventFunc](ta.ioKit, common.IOHIDServiceClientCopyEventSym)
ioHIDEventGetFloatValue := common.GetFunc[common.IOHIDEventGetFloatValueFunc](ta.ioKit, common.IOHIDEventGetFloatValueSym) ioHIDEventGetFloatValue := common.GetFunc[common.IOHIDEventGetFloatValueFunc](ta.ioKit, common.IOHIDEventGetFloatValueSym)
system := ta.ioHIDEventSystemClientCreate(common.KCFAllocatorDefault)
ta.ioHIDEventSystemClientSetMatching(uintptr(system), uintptr(ta.sensors)) ta.ioHIDEventSystemClientSetMatching(uintptr(system), uintptr(ta.sensors))
matchingsrvs := ta.ioHIDEventSystemClientCopyServices(uintptr(system)) matchingsrvs := ta.ioHIDEventSystemClientCopyServices(uintptr(system))
if matchingsrvs == nil { if matchingsrvs == nil {
return nil return nil
} }
defer ta.cfRelease(uintptr(matchingsrvs))
count := ta.cfArrayGetCount(uintptr(matchingsrvs)) count := ta.cfArrayGetCount(uintptr(matchingsrvs))
@ -155,7 +158,6 @@ func (ta *temperatureArm) getThermalValues() []float64 {
values = append(values, temp) values = append(values, temp)
} }
ta.cfRelease(uintptr(matchingsrvs))
return values return values
} }

Loading…
Cancel
Save