57 lines
1.4 KiB
Go
57 lines
1.4 KiB
Go
//go:build darwin
|
|
|
|
package oomprofile
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"os"
|
|
"unsafe"
|
|
_ "unsafe"
|
|
)
|
|
|
|
func isExecutable(protection int32) bool {
|
|
return (protection&_VM_PROT_EXECUTE) != 0 && (protection&_VM_PROT_READ) != 0
|
|
}
|
|
|
|
func (b *profileBuilder) readMapping() {
|
|
if !machVMInfo(b.addMapping) {
|
|
b.addMappingEntry(0, 0, 0, "", "", true)
|
|
}
|
|
}
|
|
|
|
func machVMInfo(addMapping func(lo uint64, hi uint64, off uint64, file string, buildID string)) bool {
|
|
added := false
|
|
addr := uint64(0x1)
|
|
for {
|
|
var regionSize uint64
|
|
var info machVMRegionBasicInfoData
|
|
kr := machVMRegion(&addr, ®ionSize, unsafe.Pointer(&info))
|
|
if kr != 0 {
|
|
if kr == _MACH_SEND_INVALID_DEST {
|
|
return true
|
|
}
|
|
return added
|
|
}
|
|
if isExecutable(info.Protection) {
|
|
addMapping(addr, addr+regionSize, binary.LittleEndian.Uint64(info.Offset[:]), regionFilename(addr), "")
|
|
added = true
|
|
}
|
|
addr += regionSize
|
|
}
|
|
}
|
|
|
|
func regionFilename(address uint64) string {
|
|
buf := make([]byte, _MAXPATHLEN)
|
|
n := procRegionFilename(os.Getpid(), address, unsafe.SliceData(buf), int64(cap(buf)))
|
|
if n == 0 {
|
|
return ""
|
|
}
|
|
return string(buf[:n])
|
|
}
|
|
|
|
//go:linkname machVMRegion runtime/pprof.mach_vm_region
|
|
func machVMRegion(address *uint64, regionSize *uint64, info unsafe.Pointer) int32
|
|
|
|
//go:linkname procRegionFilename runtime/pprof.proc_regionfilename
|
|
func procRegionFilename(pid int, address uint64, buf *byte, buflen int64) int32
|