Skip to content

Commit

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

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.

    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
  • Loading branch information
stevendanna authored Mar 14, 2024
1 parent 69bddb5 commit 6aea86e
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- darwin: Fix checkptr error in `(*Mem).Get` for Go 1.22.

### Changed

### Deprecated
Expand Down
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 6aea86e

Please sign in to comment.