Skip to content

Commit

Permalink
fix checkptr in (*Mem).Get on darwin on Go 1.22
Browse files Browse the repository at this point in the history
The unit tests currently fail under race on Go 1.22 on Darwin.

    > go test -race -v -run TestMem

    fatal error: checkptr: converted pointer straddles multiple allocations

    goroutine 35 gp=0xc000104c40 m=0 mp=0x104af4d00 [running]:
    runtime.throw({0x1048d66ee?, 0xc00012c7d8?})
            /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/panic.go:1023 +0x40 fp=0xc000067cc0 sp=0xc000067c90 pc=0x1046b8a20
    runtime.checkptrAlignment(0x1048ca639?, 0xa?, 0x104af4d00?)
            /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/checkptr.go:26 +0x70 fp=0xc000067ce0 sp=0xc000067cc0 pc=0x1046861e0
    github.com/elastic/gosigar.sysctlbyname({0x1048ca639, 0xa}, {0x10494bca0, 0xc000067e30})
            /Users/ssd/src/gosigar/sigar_common_darwin.go:483 +0xa8 fp=0xc000067d60 sp=0xc000067ce0 pc=0x1048800d8
    github.com/elastic/gosigar.(*Mem).Get(0xc000067e30)
            /Users/ssd/src/gosigar/sigar_common_darwin.go:48 +0x78 fp=0xc000067df0 sp=0xc000067d60 pc=0x10487d2a8
    github.com/elastic/gosigar_test.TestMem(0xc0001349c0)
            /Users/ssd/src/gosigar/sigar_interface_test.go:37 +0x3c fp=0xc000067ed0 sp=0xc000067df0 pc=0x10488242c
    testing.tRunner(0xc0001349c0, 0x104996310)
            /opt/homebrew/Cellar/go/1.22.1/libexec/src/testing/testing.go:1689 +0x184 fp=0xc000067fa0 sp=0xc000067ed0 pc=0x10478d1c4
    testing.(*T).Run.gowrap1()
            /opt/homebrew/Cellar/go/1.22.1/libexec/src/testing/testing.go:1742 +0x44 fp=0xc000067fd0 sp=0xc000067fa0 pc=0x10478e664
    runtime.goexit({})
            /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/asm_arm64.s:1222 +0x4 fp=0xc000067fd0 sp=0xc000067fd0 pc=0x1046f5894
    created by testing.(*T).Run in goroutine 1
            /opt/homebrew/Cellar/go/1.22.1/libexec/src/testing/testing.go:1742 +0x5e8

This is because syscall.Sysctl assumes that all return values are C
strings and truncates the final byte if it is NUL.  For Sysctl's that
return integers, attempting to interpret the 7 byte buffer results in
the checkptr violation.

Here, we fix this by using the sys/unix packages SysctlUint64.
  • Loading branch information
stevendanna committed Mar 13, 2024
1 parent 69bddb5 commit 2c63039
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions sigar_common_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"syscall"
"time"
"unsafe"

"golang.org/x/sys/unix"
)

// Get fetches LoadAverage data
Expand Down Expand Up @@ -471,21 +473,23 @@ func vmInfo(vmstat *C.vm_statistics_data_t) error {

// generic Sysctl buffer unmarshalling
func sysctlbyname(name string, data interface{}) (err error) {
val, err := syscall.Sysctl(name)
if err != nil {
return err
}

buf := []byte(val)

switch v := data.(type) {
case *uint64:
*v = *(*uint64)(unsafe.Pointer(&buf[0]))
return
}
res, err := unix.SysctlUint64(name)
if err != nil {
return err
}
*v = res
return nil
default:
val, err := syscall.Sysctl(name)
if err != nil {
return err
}

bbuf := bytes.NewBuffer([]byte(val))
return binary.Read(bbuf, binary.LittleEndian, data)
bbuf := bytes.NewBuffer([]byte(val))
return binary.Read(bbuf, binary.LittleEndian, data)
}
}

func taskInfo(pid int, info *C.struct_proc_taskallinfo) error {
Expand Down

0 comments on commit 2c63039

Please sign in to comment.